Follow-up to #1207, addressing items from the cargo validator review.
**Scoped to cargo + shared helpers — no behavior change for existing
npm/pypi/nuget/oci/mcpb publishers.** Safe to merge and promote.
### Changes
**SSRF hardening of the two-call README retrieval**
- Pin the step-2 README URL to an allowed host (`static.crates.io` in
prod; the base host under test) *before* fetching, so a metadata
response can't steer the validator at an internal/attacker host.
- `CheckRedirect` policy pins every redirect hop to the same allowlist
(the initial URL being pinned isn't enough if an upstream 3xx is
followed).
- Cap the README body with `io.LimitReader` (5 MiB).
> Not publisher-exploitable today (the URL comes from crates.io), so
this is defense-in-depth — but it makes the "host is pinned" guarantee
hold in code rather than rely on crates.io's behavior.
**Clearer status handling** (previously any non-5xx/non-200 collapsed to
"not found")
- **429** → reported as transient/retryable, at both the metadata and
README steps.
- **403** → disambiguated via the crate-version endpoint:
genuinely-missing stays "not found"; *exists-but-no-README* gets an
actionable "add a README with `mcp-name` and republish" message (mirrors
the NuGet validator). This continues the 5xx-vs-403 diagnostic split
@P4ST4S started in the #1207 review — thanks!
**Shared `containsMCPNameToken` helper**
Boundary-anchored ownership-token match (prevents prefix confusion, e.g.
a README declaring `io.github.acme/widget-pro` satisfying a claim for
`io.github.acme/widget`), used here **by the cargo validator only**.
Adopting it in PyPI/NuGet is a separate follow-up because it's a
behavior change for those already-live registries.
**Tests & docs**
Hermetic positive `ServerNameFormats`; combined fixture gains a
version-existence endpoint + cases for 403-missing vs 403-no-README,
429, and prefix-confusion rejection; new foreign-README-host (SSRF)
test; internal test for the helper. Docs: list `crates.io` in the
registry-requirements list + the `Package` model doc.
### Testing
`go build`, `go vet`, full `./internal/validators/...` suite (incl. live
cargo positive), `make check-schema`, `validate-examples` all pass. No
new `golangci-lint` findings.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bumps [github.com/jackc/pgx/v5](https://github.com/jackc/pgx) from 5.9.2
to 5.10.0.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/jackc/pgx/blob/master/CHANGELOG.md">github.com/jackc/pgx/v5's
changelog</a>.</em></p>
<blockquote>
<h1>5.10.0 (June 3, 2026)</h1>
<p>This release includes a significant amount of hardening against
malicious or compromised PostgreSQL servers,
contributed by Sean Chittenden at CrowdStrike, Inc. This work bounds
binary decoders against attacker-controlled
message sizes, caps server-supplied SCRAM iteration counts, adds
<code>require_auth</code> to restrict which authentication
methods a server may use (mitigating downgrade attacks under
<code>sslmode=prefer</code>), and ensures cancellation requests are
sent over TLS when the original connection used TLS.</p>
<h2>Features</h2>
<ul>
<li>Add <code>require_auth</code> to restrict accepted server
authentication methods (Sean Chittenden at CrowdStrike, Inc.)</li>
<li>Add <code>ParseConfigOptions.ConnStringAllowedKeys</code> to
restrict allowed connection string keys (Sean Chittenden at CrowdStrike,
Inc.)</li>
<li>Add <code>StructArgs</code> and <code>StrictStructArgs</code> for
<code>@</code>-named queries (Tubelight30)</li>
<li>Add <code>ErrConnClosed</code> sentinel error and unwrap it from
<code>connLockError</code> (Charlie Tonneslan)</li>
<li>pgxpool: check if connection is expired before acquire
(arthurdotwork)</li>
</ul>
<h2>Security Hardening</h2>
<ul>
<li>Encrypt <code>CancelRequest</code> connection when the primary
connection used TLS (Sean Chittenden at CrowdStrike, Inc.)</li>
<li>Cap server-supplied SCRAM iteration count (Sean Chittenden at
CrowdStrike, Inc.)</li>
<li>Default Frontend max message body length to ~1 GiB (Sean Chittenden
at CrowdStrike, Inc.)</li>
<li>Bound hstore binary decode against malicious server input (Sean
Chittenden at CrowdStrike, Inc.)</li>
<li>Bound array binary decode element length against remaining message
bytes (Sean Chittenden at CrowdStrike, Inc.)</li>
<li>Bound array element count against remaining message bytes (Sean
Chittenden at CrowdStrike, Inc.)</li>
<li>Bound range, multirange, and tsvector binary decoders (Sean
Chittenden at CrowdStrike, Inc.)</li>
<li>Document secure connection configuration (Sean Chittenden at
CrowdStrike, Inc.)</li>
<li>Fix panic on malformed geometric text; return an error instead
(MaIII)</li>
</ul>
<h2>Fixes</h2>
<ul>
<li>Fix scanning <code>"char"</code> (OID 18) into
<code>*string</code> in binary format (luongs3)</li>
<li>Fix handling of typed-nil <code>driver.Valuer</code> in array and
composite codecs (Donncha Fahy)</li>
<li>Fix <code>CopyData.Data</code> hex decoding in
<code>UnmarshalJSON</code> (Charlie Tonneslan)</li>
<li>Fix data race when context is cancelled during connect</li>
<li>Fix <code>parseKeywordValueSettings</code> rejecting trailing
whitespace (alliasgher)</li>
<li>pgconn: preserve full error chain in
<code>normalizeTimeoutError</code> (Charlie Tonneslan)</li>
<li>pgconn: use a fresh context for the fallback connection in
<code>connectPreferred</code> (Charlie Tonneslan)</li>
<li>pgxpool: fix <code>MaxLifetimeDestroyCount</code> and ping order for
acquire-time expiry check</li>
<li>Add missing error check of <code>rows.Err</code> to load types (Jen
Altavilla)</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="7293fb1112"><code>7293fb1</code></a>
Update changelog for v5.10.0</li>
<li><a
href="1ade285284"><code>1ade285</code></a>
pgconn: document secure connection configuration</li>
<li><a
href="b4d6d4d1be"><code>b4d6d4d</code></a>
pgtype: bound range, multirange, and tsvector binary decoders</li>
<li><a
href="0639b37f8f"><code>0639b37</code></a>
pgconn: add ParseConfigOptions.ConnStringAllowedKeys</li>
<li><a
href="b28e65b0c3"><code>b28e65b</code></a>
pgtype: bound array element count against remaining message bytes</li>
<li><a
href="cd1f389d37"><code>cd1f389</code></a>
pgtype: bound array binary decode element length against remaining
bytes</li>
<li><a
href="ff27b5bbea"><code>ff27b5b</code></a>
pgtype: bound hstore binary decode against malicious server input</li>
<li><a
href="a6002e12a8"><code>a6002e1</code></a>
pgproto3: default Frontend max message body length to ~1 GiB</li>
<li><a
href="44f61732ec"><code>44f6173</code></a>
pgconn: cap server-supplied SCRAM iteration count</li>
<li><a
href="1a976f7bb9"><code>1a976f7</code></a>
pgconn: add require_auth to restrict accepted server auth methods</li>
<li>Additional commits viewable in <a
href="https://github.com/jackc/pgx/compare/v5.9.2...v5.10.0">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
> **Update — 2026-06-01 (commit 1f3be53)**
>
> - **All @P4ST4S review feedback addressed** — positive-path hermetic
mock + live anchor against `rust-faf-mcp v0.3.1`; 5xx routed as
transient; doc comment qualified. See the [close-out
comment](https://github.com/modelcontextprotocol/registry/pull/1207#issuecomment-4589711057)
for the per-item breakdown.
> - **Runtime-model question RESOLVED** — `package-types.mdx` documents
cargo and MCPB as both first-class Rust MCP distribution paths (cargo
for source-distributed, MCPB for prebuilt-binary). The "Open question"
section below was the original draft framing; the doc now ships the
resolution.
> - **Cargo-specific gotcha discovered and documented** — crates.io
strips HTML comments during README rendering, unlike PyPI/NuGet.
`package-types.mdx` now spells this out so cargo authors don't ship
invisible mcp-name tokens (which is exactly what happened to
`rust-faf-mcp v0.3.0`; fixed in v0.3.1).
> - **Stale reference removed in this update** — the "Out of scope" line
mentioning `docs/guides/publishing/publish-cargo.md` pointed at a path
that doesn't exist. The canonical per-type doc is
`docs/modelcontextprotocol-io/package-types.mdx`; the Cargo section has
been added there directly.
> - **Two real-world Rust MCP servers queued for day-one register**:
`rust-faf-mcp v0.3.1` (live, end-to-end validated by the new live test)
and `perfetto-mcp-rs` ([@0xZOne](https://github.com/0xZOne) in #1055).
> - **Tests:** 19/19 cargo tests pass (16 existing + 2 hermetic + 1 live
anchor). `make validate` clean. `golangci-lint` 0 issues.
---
Adds support for `registryType: cargo` so Rust MCP servers published to
crates.io can be registered through the
documented validation flow rather than the MCPB binary-packaging
workaround. Closes#1055.
## Motivation and Context
#1055 noted that crates.io has ~1,800 MCP-related packages with no
direct path into the registry — only the MCPB
binary-packaging workaround. This PR adds first-class support for cargo
as a package registry type: schema +
API surface, validator, integration tests, and a documented example. The
publishing guide
(`docs/guides/publishing/publish-cargo.md`) follows on this branch once
the runtime-model direction in
**Additional context** is settled.
## How Has This Been Tested?
- **`make validate`** — clean. Schema-vs-openapi sync verified; 17/17
examples in `generic-server-json.md`
validate against the schema; `expectedServerJSONCount` bumped 16 → 17 to
match the new Cargo example.
- **`go test ./internal/validators/...`** — passes. 16 cargo validator
sub-cases across 4 test functions, run
against real crates.io (~2.5s wall):
- Input validation rejection paths
- Registry-baseURL rejection (4 variants: different host, trailing
slash, http-not-https, subdomain typo)
- Ownership validation against real crates (`serde`, `tokio`, `rand`) —
all correctly rejected for missing
`mcp-name` token
- Server-name format variations (canonical `io.github.OWNER/REPO`,
multi-hyphen, underscore, numeric suffix)
- **Positive-path test** — gated on `rust-faf-mcp` v0.2.3+ being
published with `mcp-name:
io.github.Wolfe-Jam/rust-faf-mcp` in its README. Reserved as a TODO in
`cargo_test.go`; uncomments to become the
live anchor once that publish lands.
- **Local `make test-unit`** — not run due to a Go toolchain version
quirk on my workstation (project
auto-downloads 1.26.0; my local `go` is 1.25.6, causing compile
mismatch). CI will exercise the full
PostgreSQL-backed suite.
## Breaking Changes
None. This is an additive change — `cargo` joins the supported
`registryType` enum alongside
`npm`/`pypi`/`nuget`/`oci`/`mcpb`. Existing publishes continue to work
unchanged.
## Types of changes
- [x] New feature (non-breaking change which adds functionality)
- [x] Documentation update (new Cargo example in
`generic-server-json.md`)
## Checklist
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [x] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## Additional context
### Validator design — two-call retrieval on the documented API
`internal/validators/registries/cargo.go` mirrors the PyPI validator's
README-token approach (substring-match
`mcp-name: <serverName>`), with a two-call retrieval pattern to stay on
the documented public crates.io API:
1. `GET /api/v1/crates/{name}/{version}/readme` returns 200 OK with a
JSON pointer (`{"url":
"https://static.crates.io/readmes/.../...html"}`) — crates.io hands us
the URL rather than emitting a 302.
2. Follow the pointer to the rendered HTML; substring-match for the
token.
The two-call pattern stays on the documented public surface. The CDN URL
layout is observed-stable, but treating
it as the entry point would mean depending on an undocumented path. With
two calls, crates.io controls where
the README lives — if they move it, the metadata endpoint hands us the
new URL.
Missing crates and missing versions surface as **403** from the CDN
(S3's default for missing keys), not 404.
The validator treats any non-200 as "not found" and surfaces the actual
status code in the error message.
### Open question — runtime model
Cargo's runtime model is genuinely different from npm/PyPI/NuGet. `cargo
install` is one-time (binary lands on
PATH at `~/.cargo/bin`), not per-invocation like `npx`, `uvx`, or `dnx`
(the new one in .NET 10 SDK Preview 6+).
The new Cargo example in `generic-server-json.md` annotates this
honestly and omits `runtimeHint`.
If a different framing is preferred — e.g. recommending **MCPB**
(prebuilt binary distribution via GitHub
Releases) as the primary path for Rust MCP servers instead of cargo —
happy to adjust the documentation
accordingly. The schema + validator code in this PR is **additive** and
doesn't force a recommendation either
way; a Rust author who chooses cargo can use it, and one who prefers
MCPB still can.
### Out of scope (deferred)
- **`docs/guides/publishing/publish-cargo.md`** — follows on this branch
once the runtime-model direction above
is settled.
- **Publisher CLI `Cargo.toml` autodetect** in
`cmd/publisher/commands/init.go` — separate concern, separate PR.
- **Positive-path validator test** — gated on `rust-faf-mcp` v0.2.3+
publishing as noted in *How Has This Been
Tested?*.
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Radoslav Dimitrov <radoslav@stacklok.com>
## Summary
- Bumps `golang.org/x/net` from v0.53.0 to v0.55.0 to fix
[GO-2026-5026](https://pkg.go.dev/vuln/GO-2026-5026) (failure to reject
ASCII-only Punycode-encoded labels in `golang.org/x/net/idna`).
- govulncheck flagged the vuln via `auth.DefaultHTTPKeyFetcher.FetchKey`
→ `http.Client.Do` → `idna.ToASCII` at
`internal/api/handlers/v0/auth/http.go:191`.
- Also brings in associated `x/crypto`, `x/sys`, `x/text` bumps via `go
mod tidy`.
This unblocks open dependabot PRs (e.g. #1298) that are failing CI on
the same govulncheck finding despite not touching the root module.
## Test plan
- [x] `go build ./...`
- [x] `govulncheck` no longer reports GO-2026-5026 locally
- [ ] CI passes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bumps the actions group with 1 update:
[goreleaser/goreleaser-action](https://github.com/goreleaser/goreleaser-action).
Updates `goreleaser/goreleaser-action` from 7.2.1 to 7.2.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/goreleaser/goreleaser-action/releases">goreleaser/goreleaser-action's
releases</a>.</em></p>
<blockquote>
<h2>v7.2.2</h2>
<h2>What's Changed</h2>
<ul>
<li>ci(deps): bump the actions group with 3 updates by <a
href="https://github.com/dependabot"><code>@dependabot</code></a>[bot]
in <a
href="https://redirect.github.com/goreleaser/goreleaser-action/pull/560">goreleaser/goreleaser-action#560</a></li>
<li>fix: nightly resolution to select newest published release by <a
href="https://github.com/Copilot"><code>@Copilot</code></a> in <a
href="https://redirect.github.com/goreleaser/goreleaser-action/pull/562">goreleaser/goreleaser-action#562</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/Copilot"><code>@Copilot</code></a> made
their first contribution in <a
href="https://redirect.github.com/goreleaser/goreleaser-action/pull/562">goreleaser/goreleaser-action#562</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/goreleaser/goreleaser-action/compare/v7...v7.2.2">https://github.com/goreleaser/goreleaser-action/compare/v7...v7.2.2</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="5daf1e915a"><code>5daf1e9</code></a>
fix: nightly resolution to select newest published release (<a
href="https://redirect.github.com/goreleaser/goreleaser-action/issues/562">#562</a>)</li>
<li><a
href="5cc7ebb73d"><code>5cc7ebb</code></a>
ci: update actions</li>
<li><a
href="702f5f91c9"><code>702f5f9</code></a>
ci(deps): bump the actions group with 3 updates (<a
href="https://redirect.github.com/goreleaser/goreleaser-action/issues/560">#560</a>)</li>
<li>See full diff in <a
href="1a80836c5c...5daf1e915a">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps
[github.com/pulumi/pulumi/sdk/v3](https://github.com/pulumi/pulumi) from
3.238.0 to 3.242.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pulumi/pulumi/releases">github.com/pulumi/pulumi/sdk/v3's
releases</a>.</em></p>
<blockquote>
<h2>v3.242.0</h2>
<h2>3.242.0 (2026-05-19)</h2>
<h3>Features</h3>
<ul>
<li>
<p>[cli] Add a <code>pulumi</code> package for npx support</p>
</li>
<li>
<p>[cli] Add the <code>pulumi org member edit</code> command
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23235">#23235</a></p>
</li>
<li>
<p>[cli] Add the <code>pulumi org member remove</code> command
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23237">#23237</a></p>
</li>
<li>
<p>[cli/cloud] Add <code>pulumi deployment get</code> to retrieve
details for a specific deployment
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23238">#23238</a></p>
</li>
<li>
<p>[cli/cloud] Add <code>pulumi insights account scan get
<account> <scan-id></code> to show the full workflow run for
a single Insights scan
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23255">#23255</a></p>
</li>
<li>
<p>[cli/cloud] Add <code>pulumi insights account scan list
<account></code> to discover recent scan IDs to feed into
<code>pulumi insights account scan log</code>
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23255">#23255</a></p>
</li>
<li>
<p>[cli/deployment] Add dedicated flags for each deployment setting
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23236">#23236</a></p>
</li>
<li>
<p>[cli/do] Add the start of <code>pulumi do</code>
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23176">#23176</a></p>
</li>
<li>
<p>[cli/neo] Add <code>--print</code>/<code>-p</code> to <code>pulumi
neo</code> to run a single prompt non-interactively and print the
agent's final response to stdout
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23245">#23245</a></p>
</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>
<p>[cli/cloud] Fix <code>pulumi insights account scan log --all</code>
to follow the server's pagination cursor through the end of the log, and
render <code>--job/--step</code> mode as structured lines instead of an
empty raw-string blob
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23256">#23256</a></p>
</li>
<li>
<p>[sdk] Close gzip.Writer in archiveTarGZIP to produce valid tar.gz
output
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23240">#23240</a></p>
</li>
<li>
<p>[sdkgen/python] Fix usage of ArgsDict types in typed dictionaries
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23253">#23253</a></p>
</li>
</ul>
<h2>v3.241.0</h2>
<h2>3.241.0 (2026-05-18)</h2>
<h3>Features</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pulumi/pulumi/blob/master/CHANGELOG.md">github.com/pulumi/pulumi/sdk/v3's
changelog</a>.</em></p>
<blockquote>
<h2>3.242.0 (2026-05-19)</h2>
<h3>Features</h3>
<ul>
<li>
<p>[cli] Add a <code>pulumi</code> package for npx support</p>
</li>
<li>
<p>[cli] Add the <code>pulumi org member edit</code> command
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23235">#23235</a></p>
</li>
<li>
<p>[cli] Add the <code>pulumi org member remove</code> command
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23237">#23237</a></p>
</li>
<li>
<p>[cli/cloud] Add <code>pulumi deployment get</code> to retrieve
details for a specific deployment
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23238">#23238</a></p>
</li>
<li>
<p>[cli/cloud] Add <code>pulumi insights account scan get
<account> <scan-id></code> to show the full workflow run for
a single Insights scan
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23255">#23255</a></p>
</li>
<li>
<p>[cli/cloud] Add <code>pulumi insights account scan list
<account></code> to discover recent scan IDs to feed into
<code>pulumi insights account scan log</code>
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23255">#23255</a></p>
</li>
<li>
<p>[cli/deployment] Add dedicated flags for each deployment setting
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23236">#23236</a></p>
</li>
<li>
<p>[cli/do] Add the start of <code>pulumi do</code>
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23176">#23176</a></p>
</li>
<li>
<p>[cli/neo] Add <code>--print</code>/<code>-p</code> to <code>pulumi
neo</code> to run a single prompt non-interactively and print the
agent's final response to stdout
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23245">#23245</a></p>
</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>
<p>[cli/cloud] Fix <code>pulumi insights account scan log --all</code>
to follow the server's pagination cursor through the end of the log, and
render <code>--job/--step</code> mode as structured lines instead of an
empty raw-string blob
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23256">#23256</a></p>
</li>
<li>
<p>[sdk] Close gzip.Writer in archiveTarGZIP to produce valid tar.gz
output
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23240">#23240</a></p>
</li>
<li>
<p>[sdkgen/python] Fix usage of ArgsDict types in typed dictionaries
<a
href="https://redirect.github.com/pulumi/pulumi/pull/23253">#23253</a></p>
</li>
</ul>
<h2>3.241.0 (2026-05-18)</h2>
<h3>Features</h3>
<ul>
<li>[cli] Add <code>--output json</code> to <code>pulumi preview</code>
for a structured JSON summary of the operation result
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22927">#22927</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f4db8b5f55"><code>f4db8b5</code></a>
Upgrade Pulumi HCL to v0.3.2 (<a
href="https://redirect.github.com/pulumi/pulumi/issues/23261">#23261</a>)</li>
<li><a
href="cd682b849c"><code>cd682b8</code></a>
cli: add a <code>pulumi</code> package for npx support (<a
href="https://redirect.github.com/pulumi/pulumi/issues/23145">#23145</a>)</li>
<li><a
href="e8364996b7"><code>e836499</code></a>
cli/neo: set AI_AGENT=neo for shell-tool child processes (<a
href="https://redirect.github.com/pulumi/pulumi/issues/23251">#23251</a>)</li>
<li><a
href="2560b9015f"><code>2560b90</code></a>
unhide <code>org usage</code> command tree (<a
href="https://redirect.github.com/pulumi/pulumi/issues/23259">#23259</a>)</li>
<li><a
href="4588160dba"><code>4588160</code></a>
unhide <code>org member</code> commands (<a
href="https://redirect.github.com/pulumi/pulumi/issues/23257">#23257</a>)</li>
<li><a
href="f821c0dfc7"><code>f821c0d</code></a>
unhide <code>org role</code> commands (<a
href="https://redirect.github.com/pulumi/pulumi/issues/23258">#23258</a>)</li>
<li><a
href="9356340a67"><code>9356340</code></a>
docs(contributing): minor grammar fixes (<code>PR</code> ->
<code>PRs</code>, <code>Here's</code> -> `Here are...</li>
<li><a
href="3779d16c8b"><code>3779d16</code></a>
unhide <code>org member</code> (<a
href="https://redirect.github.com/pulumi/pulumi/issues/23241">#23241</a>)</li>
<li><a
href="c28bf15134"><code>c28bf15</code></a>
unhide a couple <code>stack</code> commands (<a
href="https://redirect.github.com/pulumi/pulumi/issues/23243">#23243</a>)</li>
<li><a
href="90caf84946"><code>90caf84</code></a>
cli/cloud: fix <code>pulumi insights account scan log</code> pagination
(<a
href="https://redirect.github.com/pulumi/pulumi/issues/23256">#23256</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/pulumi/pulumi/compare/v3.238.0...v3.242.0">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## Summary
- Dependency update PRs were arriving daily across gomod (root +
`/deploy`), github-actions, and docker — creating significant review
noise.
- Switch all four update entries in `.github/dependabot.yml` from
`interval: daily` to `interval: weekly` so they batch on a weekly
cadence (Dependabot defaults to Mondays).
## Test plan
- [ ] Confirm `.github/dependabot.yml` parses correctly (Dependabot will
report a config error on the repo if not)
- [ ] Observe that new dependency PRs stop appearing daily after merge
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Summary
When the OCI validator's anonymous manifest fetch returns HTTP 429,
return a retryable error instead of `nil`. This aligns OCI with the
fail-closed behavior of the npm / PyPI / NuGet / MCPB validators, and
ensures the `io.modelcontextprotocol.server.name` label-match always
runs before a publish is accepted.
## Test plan
- [x] `go test ./internal/validators/registries/ -run TestValidateOCI`
passes locally
- [x] `gofmt` + `golangci-lint` clean on the changed file
- [ ] CI green
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bumps [github.com/go-git/go-git/v5](https://github.com/go-git/go-git)
from 5.18.0 to 5.19.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/go-git/go-git/releases">github.com/go-git/go-git/v5's
releases</a>.</em></p>
<blockquote>
<h2>v5.19.0</h2>
<h2>What's Changed</h2>
<ul>
<li>build: Update module github.com/go-git/go-git/v5 to v5.18.0
[SECURITY] (releases/v5.x) by <a
href="https://github.com/go-git-renovate"><code>@go-git-renovate</code></a>[bot]
in <a
href="https://redirect.github.com/go-git/go-git/pull/2010">go-git/go-git#2010</a></li>
<li>v5: Bump sha1cd and go-billy by <a
href="https://github.com/pjbgf"><code>@pjbgf</code></a> in <a
href="https://redirect.github.com/go-git/go-git/pull/2060">go-git/go-git#2060</a></li>
<li>v5: Align object encoding with upstream by <a
href="https://github.com/pjbgf"><code>@pjbgf</code></a> in <a
href="https://redirect.github.com/go-git/go-git/pull/2065">go-git/go-git#2065</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/go-git/go-git/compare/v5.18.0...v5.19.0">https://github.com/go-git/go-git/compare/v5.18.0...v5.19.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="bc930f4cbe"><code>bc930f4</code></a>
Merge pull request <a
href="https://redirect.github.com/go-git/go-git/issues/2065">#2065</a>
from go-git/commit-v5</li>
<li><a
href="d315264343"><code>d315264</code></a>
plumbing: object, Reset object before decode</li>
<li><a
href="6e1d34890a"><code>6e1d348</code></a>
plumbing: object, Align Tree handling with upstream</li>
<li><a
href="e134ba34cf"><code>e134ba3</code></a>
tests: Skip double checks in Git v2.11</li>
<li><a
href="1971422f6b"><code>1971422</code></a>
tests: Add git conformance tests for signing verification</li>
<li><a
href="a387aa8857"><code>a387aa8</code></a>
plumbing: object, Add ErrMalformedTag</li>
<li><a
href="f415670d90"><code>f415670</code></a>
plumbing: object, Decode Tag headers via a state machine</li>
<li><a
href="5b0cd38a62"><code>5b0cd38</code></a>
plumbing: object, Reject multi-signature commits at Verify</li>
<li><a
href="fe8ed6223a"><code>fe8ed62</code></a>
plumbing: object, Align Tag.EncodeWithoutSignature with Commit</li>
<li><a
href="98e337d5bd"><code>98e337d</code></a>
plumbing: object, Add support for Tag.SignatureSHA256</li>
<li>Additional commits viewable in <a
href="https://github.com/go-git/go-git/compare/v5.18.0...v5.19.0">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/modelcontextprotocol/registry/network/alerts).
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## Summary
`complete.md` documents three flags for `mcp-publisher publish` that the
CLI does not actually parse:
- `--file=PATH` — Path to server.json
- `--registry=URL` — Registry URL override
- `--dry-run` — Validate without publishing
Reading
[`cmd/publisher/commands/publish.go`](https://github.com/modelcontextprotocol/registry/blob/main/cmd/publisher/commands/publish.go)
and
[`cmd/publisher/main.go`](https://github.com/modelcontextprotocol/registry/blob/main/cmd/publisher/main.go)
confirms the actual interface is a single positional `PATH` argument
(default `./server.json`):
```go
serverFile := \"server.json\"
if len(args) > 0 && !strings.HasPrefix(args[0], \"-\") {
serverFile = args[0]
}
```
Registry URL is bound at login time via the saved token, and \"validate
without publishing\" is a separate `mcp-publisher validate` subcommand.
The bug user in #767 hit \"server.json not found\" precisely because
`--file .registry/server.json` is filtered out by the
`HasPrefix(args[0], \"-\")` check, leaving the default lookup in place.
## Background
The canonical reference at
[`docs/reference/cli/commands.md`](https://github.com/modelcontextprotocol/registry/blob/main/docs/reference/cli/commands.md)
was already updated to the correct positional shape. `complete.md` (the
concatenated single-file mirror of `docs/` used for LLM/quickstart
consumption) had drifted out of sync — these were the only remaining
`--file` references in the repo outside of test fixtures.
Per the discussion on the prior flag-implementation attempt in #771,
maintainers preferred fixing the documentation over adding the
unimplemented flags:
> @domdomegg: I'd lean towards removing the options from the docs.
This PR closes that loop on the last stale doc surface.
## Changes
`complete.md`: the `mcp-publisher publish` block now matches
`docs/reference/cli/commands.md` line-for-line (positional `PATH`, no
spurious flags, no dry-run example).
```diff
-mcp-publisher publish [options]
+mcp-publisher publish [PATH]
-- \`--file=PATH\` - Path to server.json (default: \`./server.json\`)
-- \`--registry=URL\` - Registry URL override
-- \`--dry-run\` - Validate without publishing
+- \`PATH\` - Path to server.json (default: \`./server.json\`)
-# Dry run validation
-mcp-publisher publish --dry-run
-
# Custom file location
-mcp-publisher publish --file=./config/server.json
+mcp-publisher publish ./config/server.json
```
Closes#767.
## Out of scope
- `cmd/publisher/README.md:17` still shows `./bin/mcp-publisher publish
--registry=http://localhost:8080` in the contributor quickstart. The
flag is silently ignored at runtime (caught by the same
`HasPrefix(\"-\")` filter). Happy to fold that fix into this PR or send
a follow-up — flagging here in case a maintainer prefers one option.
- `complete.md` is missing `mcp-publisher validate` and `mcp-publisher
status` sections that exist in `docs/reference/cli/commands.md`. Out of
scope for this single-concern PR; if there's interest, a broader sync
would be a separate PR.
## Test plan
- [x] `grep -r -- '--file' .` outside test fixtures returns 0 hits after
the change
- [x] `grep -r 'mcp-publisher publish --' docs/ complete.md` shows only
legitimate flags (`--registry` on `login`)
- [x] No code changes — `make check` not exercised since this is
doc-only
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: d 🔹 <258577966+voidborne-d@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bumps [golang.org/x/mod](https://github.com/golang/mod) from 0.35.0 to
0.36.0.
<details>
<summary>Commits</summary>
<ul>
<li><a
href="643da9ba74"><code>643da9b</code></a>
go.mod: update golang.org/x dependencies</li>
<li><a
href="ccc3cdf529"><code>ccc3cdf</code></a>
zip: include 'but content has correct sum' note in TestVCS</li>
<li><a
href="ab30318032"><code>ab30318</code></a>
zip: update zip hashes for new flate compression</li>
<li>See full diff in <a
href="https://github.com/golang/mod/compare/v0.35.0...v0.36.0">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps
[github.com/pulumi/pulumi/sdk/v3](https://github.com/pulumi/pulumi) from
3.236.0 to 3.237.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pulumi/pulumi/releases">github.com/pulumi/pulumi/sdk/v3's
releases</a>.</em></p>
<blockquote>
<h2>v3.237.0</h2>
<h2>3.237.0 (2026-05-08)</h2>
<h3>Features</h3>
<ul>
<li>
<p>[cli] Include the running command name and detected AI agent (when
present) in the User-Agent header on Pulumi Cloud API requests
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22908">#22908</a></p>
</li>
<li>
<p>[engine] Include <code>result</code> on the summary engine event
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22883">#22883</a></p>
</li>
<li>
<p>[sdkgen] Eagerly error on schemas with unconstructable types
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22890">#22890</a></p>
</li>
<li>
<p>[cli/cloud] Auto-fill <code>lang</code> and <code>os</code> query
parameters on <code>pulumi cloud api</code> GET/HEAD requests when the
matched OpenAPI operation declares them and the caller hasn't supplied
them
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22726">#22726</a></p>
</li>
<li>
<p>[cli/package] Add <code>pulumi package new</code> to bootstrap a
Pulumi package from a template
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22837">#22837</a></p>
</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>
<p>[cli] Add blank-line gaps between <code>pulumi neo</code> TUI
conversation blocks
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22846">#22846</a></p>
</li>
<li>
<p>[cli/import] Preserve <code>__</code>-prefixed keys when generating
PCL for imported resource state, so provider-defined payloads round-trip
correctly
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22856">#22856</a></p>
</li>
<li>
<p>[cli/neo] Render <code>ux__ask_user</code> clarifying questions as
questions instead of approval prompts
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22862">#22862</a></p>
</li>
<li>
<p>[cli/neo] Fix a panic when cancelling a <code>pulumi neo</code>
session
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22898">#22898</a></p>
</li>
<li>
<p>[cli/neo] Render every assistant message in the TUI scrollback so
multi-turn commentary no longer disappears between tool calls</p>
</li>
<li>
<p>[cli/neo] Return the bare stack name and canonical project name from
<code>pulumi_preview</code> and <code>pulumi_up</code> tool results
instead of echoing the raw input
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22891">#22891</a></p>
</li>
<li>
<p>[codegen/pcl] Stop reporting spurious circular references when an
<code>ignoreChanges</code>, <code>hideDiffs</code>,
<code>replaceOnChanges</code>, or <code>additionalSecretOutputs</code>
entry shares a name with a top-level node
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22916">#22916</a></p>
</li>
<li>
<p>[programgen/pcl] Fix PCL binder panic when a conditional mixes a
Promise-typed branch with a try() branch
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22907">#22907</a></p>
</li>
<li>
<p>[sdk/python] Support <code>NotRequired</code>, <code>Required</code>
and <code>total=False</code> in TypedDicts for component resource arg
types
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22858">#22858</a></p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pulumi/pulumi/blob/master/CHANGELOG.md">github.com/pulumi/pulumi/sdk/v3's
changelog</a>.</em></p>
<blockquote>
<h2>3.237.0 (2026-05-08)</h2>
<h3>Features</h3>
<ul>
<li>
<p>[cli] Include the running command name and detected AI agent (when
present) in the User-Agent header on Pulumi Cloud API requests
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22908">#22908</a></p>
</li>
<li>
<p>[engine] Include <code>result</code> on the summary engine event
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22883">#22883</a></p>
</li>
<li>
<p>[sdkgen] Eagerly error on schemas with unconstructable types
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22890">#22890</a></p>
</li>
<li>
<p>[cli/cloud] Auto-fill <code>lang</code> and <code>os</code> query
parameters on <code>pulumi cloud api</code> GET/HEAD requests when the
matched OpenAPI operation declares them and the caller hasn't supplied
them
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22726">#22726</a></p>
</li>
<li>
<p>[cli/package] Add <code>pulumi package new</code> to bootstrap a
Pulumi package from a template
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22837">#22837</a></p>
</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>
<p>[cli] Add blank-line gaps between <code>pulumi neo</code> TUI
conversation blocks
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22846">#22846</a></p>
</li>
<li>
<p>[cli/import] Preserve <code>__</code>-prefixed keys when generating
PCL for imported resource state, so provider-defined payloads round-trip
correctly
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22856">#22856</a></p>
</li>
<li>
<p>[cli/neo] Render <code>ux__ask_user</code> clarifying questions as
questions instead of approval prompts
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22862">#22862</a></p>
</li>
<li>
<p>[cli/neo] Fix a panic when cancelling a <code>pulumi neo</code>
session
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22898">#22898</a></p>
</li>
<li>
<p>[cli/neo] Render every assistant message in the TUI scrollback so
multi-turn commentary no longer disappears between tool calls</p>
</li>
<li>
<p>[cli/neo] Return the bare stack name and canonical project name from
<code>pulumi_preview</code> and <code>pulumi_up</code> tool results
instead of echoing the raw input
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22891">#22891</a></p>
</li>
<li>
<p>[codegen/pcl] Stop reporting spurious circular references when an
<code>ignoreChanges</code>, <code>hideDiffs</code>,
<code>replaceOnChanges</code>, or <code>additionalSecretOutputs</code>
entry shares a name with a top-level node
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22916">#22916</a></p>
</li>
<li>
<p>[programgen/pcl] Fix PCL binder panic when a conditional mixes a
Promise-typed branch with a try() branch
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22907">#22907</a></p>
</li>
<li>
<p>[sdk/python] Support <code>NotRequired</code>, <code>Required</code>
and <code>total=False</code> in TypedDicts for component resource arg
types
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22858">#22858</a></p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="dc35aff826"><code>dc35aff</code></a>
only don't run CI if changelog/config.yaml changes (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22937">#22937</a>)</li>
<li><a
href="a38b7dce73"><code>a38b7dc</code></a>
cli/neo: keep prior streaming text when the agent emits a new turn (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22897">#22897</a>)</li>
<li><a
href="6d84bb5ed7"><code>6d84bb5</code></a>
add continue-on-error to upload code coverage and upload codecov test
results...</li>
<li><a
href="8377d1277e"><code>8377d12</code></a>
Eagerly error on schemas with unconstructable types (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22890">#22890</a>)</li>
<li><a
href="9d209a07ad"><code>9d209a0</code></a>
bump java and yaml dependencies (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22932">#22932</a>)</li>
<li><a
href="dd82f69c24"><code>dd82f69</code></a>
LocalWorkspace.nested_config: use a new stack per test (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22926">#22926</a>)</li>
<li><a
href="c5180568c9"><code>c518056</code></a>
Fix flaky TestFuzz: targeted update with refresh + deleted parent (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22925">#22925</a>)</li>
<li><a
href="46486da224"><code>46486da</code></a>
Thread workspace.Context to ProviderFromSource (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22880">#22880</a>)</li>
<li><a
href="ad42ef389e"><code>ad42ef3</code></a>
increase nodejs automation API timeout (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22920">#22920</a>)</li>
<li><a
href="0b8a78bd77"><code>0b8a78b</code></a>
Test on Node.js 26 and drop 20 (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22872">#22872</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/pulumi/pulumi/compare/v3.236.0...v3.237.0">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps the actions group with 1 update:
[sigstore/cosign-installer](https://github.com/sigstore/cosign-installer).
Updates `sigstore/cosign-installer` from 4.1.1 to 4.1.2
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/sigstore/cosign-installer/releases">sigstore/cosign-installer's
releases</a>.</em></p>
<blockquote>
<h2>v4.1.2</h2>
<h2>What's Changed</h2>
<ul>
<li>Bump cosign to 3.0.6 in <a
href="https://redirect.github.com/sigstore/cosign-installer/pull/232">sigstore/cosign-installer#232</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="6f9f177880"><code>6f9f177</code></a>
Bump cosign to 3.0.6 (<a
href="https://redirect.github.com/sigstore/cosign-installer/issues/232">#232</a>)</li>
<li><a
href="b5e753ae2d"><code>b5e753a</code></a>
Bump actions/github-script from 8.0.0 to 9.0.0 (<a
href="https://redirect.github.com/sigstore/cosign-installer/issues/230">#230</a>)</li>
<li><a
href="115e4ce455"><code>115e4ce</code></a>
Bump actions/setup-go from 6.3.0 to 6.4.0 (<a
href="https://redirect.github.com/sigstore/cosign-installer/issues/226">#226</a>)</li>
<li>See full diff in <a
href="cad07c2e89...6f9f177880">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Radoslav Dimitrov <radoslav@stacklok.com>
## Summary
Bumps `golang.org/x/net` from `v0.52.0` to `v0.53.0` to address
`GO-2026-4918` (HTTP/2 transport infinite loop on bad
`SETTINGS_MAX_FRAME_SIZE`). `go mod tidy` also pulls
`golang.org/x/crypto` to v0.50.0 and `golang.org/x/text` to v0.36.0.
## Why now
`govulncheck` is failing on `main` and every open Dependabot PR (#1263,
#1264, #1265) after the 2026-05 Go security release. The findings split
into:
- **One we control** — `golang.org/x/net@v0.52.0` → fixed in `v0.53.0`.
Addressed here.
- **Six stdlib findings** (`GO-2026-4986`, `4982`, `4980`, `4977`,
`4971`, and the stdlib half of `4918`) — all fixed in `go1.26.3`. We
deliberately do **not** pin a Go patch in the workflow: `go-version:
'stable'` will pick up `1.26.3` automatically once the
`actions/go-versions` manifest catches up, with no workflow maintenance.
## Test plan
- [x] `go build ./...`
- [x] `go vet ./...`
- [x] `GOTOOLCHAIN=go1.26.3 govulncheck ./...` → "No vulnerabilities
found."
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Summary
The DNS and HTTP authentication guides currently run `openssl genpkey
-algorithm Ed25519 -out key.pem` without caveat. macOS ships LibreSSL as
the system `openssl` binary, and LibreSSL doesn't implement Ed25519 in
`genpkey` — so the very first command in the Ed25519 codepath errors out
with:
```
Algorithm Ed25519 not found
```
A first-time integrator on macOS hits this immediately, with no path to
a fix from the docs alone. Cost me ~5 minutes earlier today before I
figured out I needed `brew install openssl@3` and an explicit binary
path.
This PR adds a `<Note>` callout to the **DNS Authentication** section
right above the Ed25519 codepath, and a shorter cross-reference Note in
the **HTTP Authentication** section since the same `openssl genpkey
-algorithm Ed25519` commands appear there. The ECDSA P-384 codepath
works on LibreSSL, so it's untouched.
## Test plan
- [x] Verified locally that `/opt/homebrew/opt/openssl@3/bin/openssl
genpkey -algorithm Ed25519 -out key.pem` works on macOS Darwin 25.4.0
- [x] Verified the system `/usr/bin/openssl genpkey -algorithm Ed25519
-out key.pem` fails with `Algorithm Ed25519 not found` on the same
machine (LibreSSL 3.3.6)
- [x] Verified the published `ai.ravenmcp/raven-mcp` flow end-to-end
with the OpenSSL 3 binary
- [ ] Markdown rendering of the `<Note>` callouts — relying on the
existing `<Note>` pattern in this file (line 6) to validate the syntax
Co-authored-by: Radoslav Dimitrov <radoslav@stacklok.com>
## Summary
- Add a new **Registry Implementations** section to
`docs/community-projects.md` for self-hostable servers that implement
the MCP Registry API spec.
- Move existing **ToolSDK MCP Registry** entry from "Other" into the new
section.
- Add **ToolHive Registry Server**
(https://github.com/stacklok/toolhive-registry-server) to the new
section.
## Test plan
- [x] `docs/community-projects.md` renders correctly (markdown only, no
build step).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Summary
- Bump `mcp-registry:imageTag` from `1.7.7` → `1.7.8` in
`deploy/Pulumi.gcpProd.yaml`
- v1.7.8 ships the metrics fix that stops counting client-cancelled
requests as server errors (#1255). Under scraper-driven load, clients
with short timeouts close the socket while PG is still iterating; the
handler converts `context.Canceled` to a 500 and the metric middleware
was bumping `mcp_registry_http_errors_total` even though NGINX recorded
499 and never delivered a response. This is what's been firing the daily
~17:00 UTC `Availability dropped below 95%` alert.
- Also includes a CI-only `pulumi/actions` 6.6.1 → 7.0.0 bump (#1254).
No registry runtime impact.
- Staging is on `4e14707` (the v1.7.8 commit) and
`staging.registry.modelcontextprotocol.io/v0.1/version` reports it.
## Test plan
- [ ] Confirm release workflow's `ko-push` job has published
`ghcr.io/modelcontextprotocol/registry:1.7.8` before merging
- [ ] Watch deploy-production roll the registry pods to `1.7.8`
- [ ] Hit `https://registry.modelcontextprotocol.io/v0.1/version` and
confirm `git_commit` matches `4e147072f0`
- [ ] Through the next ~17:00 UTC scraper burst, watch in Prometheus:
- `mcp_registry_http_errors_total{status_code="500",
path="/v0.1/servers"}` should stay flat
- `mcp_registry_http_requests_total{status_code="499",
path="/v0.1/servers"}` should grow during the burst
- The `Availability dropped below 95%` alert should not fire on
cancellation-only bursts
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Summary
- Remap recorded status to `499` (NGINX-style "client closed") when
`ctx.Context().Err()` is `context.Canceled` after the handler returns
- Skip the `http_errors_total` increment for `499`s so the availability
metric reflects server-visible errors only
## Why
Under scraper-driven load, clients with short timeouts paginate
`/v0.1/servers`, give up while PG is busy, and close the TCP connection.
The handler's DB iteration returns `context canceled`, the handler
converts that to `huma.Error500InternalServerError`, and tries to write
a response to the now-closed socket. NGINX records `499` (client closed)
and never delivers anything to the client — but the registry's
middleware records `status_code=500` and bumps
`mcp_registry_http_errors_total`.
That's what's been firing the `Availability dropped below 95%` alert
during the daily 17:00 UTC bursts. Recent prod numbers from one pod
(~19h uptime):
```
mcp_registry_http_errors_total{path="/v0.1/servers", status_code="500"} 7396
mcp_registry_http_errors_total{path="/v0.1/servers/{serverName}/versions", status_code="500"} 283
mcp_registry_http_errors_total{path="/v0/servers", status_code="500"} 352
```
…against zero 5xx in NGINX ingress logs over the same window. The alert
was correct *given the data it had*; the data was misclassifying client
cancellations as server errors.
## What this does
In `internal/api/router/router.go` (the metric middleware): after
`next(ctx)`, check `ctx.Context().Err()`. If it's `context.Canceled`,
override `statusCode` to `499` and skip the error counter. Requests
counter and duration histogram still record so the cancellation rate
stays visible.
`context.DeadlineExceeded` is intentionally **not** remapped — that
would indicate a server-side timeout if we ever add per-request
deadlines, and should still count as a server error.
## What this does *not* do
- Doesn't reduce the underlying load (ServiceNow + notion catalog
scrapers driving the daily peak — separate work, see the `updated_since`
outreach we're doing).
- Doesn't change handler behaviour — handlers still call
`huma.Error500…` on `context.Canceled`. We could short-circuit earlier
(return without writing) to save the work, but that's a bigger refactor
and the metric fix unblocks the alert immediately.
## Companion change (no code, just a Grafana annotation tweak)
The `Availability dropped below 95%` alert (UID `bexrc60etvhmoa`)
currently has the annotation:
> No. of 5xx are increased from acceptable limit i.e. 5% of total
throughput
The query is on `mcp_registry_http_errors_total`, not 5xx specifically.
After this change the count is meaningful again, but the wording is
still misleading. Suggest updating to:
> Internal error rate exceeded 5% of total throughput
(no PromQL change required.)
## Test plan
- [x] `go test ./internal/api/router/...` — new test passes
- [x] `golangci-lint run ./internal/...` — clean
- [ ] After merge, watch a daily 17:00 UTC burst —
`mcp_registry_http_errors_total{status_code="500",
path="/v0.1/servers"}` should stay flat while
`mcp_registry_http_requests_total{status_code="499",
path="/v0.1/servers"}` grows. Availability alert should not fire on
cancellation-only bursts.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Summary
- Bump `mcp-registry:imageTag` from `1.7.6` → `1.7.7` in
`deploy/Pulumi.gcpProd.yaml`
- v1.7.7 is a security patch covering three findings (validator
hardening, attribute-context UI escaping, IPv6 SSRF blocklist
extension); see the v1.7.7 release notes
- Staging is on `f5f40bd` (the v1.7.7 commit) and verified end-to-end:
- `/v0.1/version` reports the new commit
- `/v0.1/validate` rejects a poisoned `websiteUrl` with
`website-url-invalid-characters`
- `/` HTML serves the `escapeAttr` helper
## Test plan
- [ ] Confirm release workflow's `ko-push` job has finished publishing
`ghcr.io/modelcontextprotocol/registry:1.7.7` before merging
- [ ] Watch deploy-production workflow rolls the registry pods to
`1.7.7`
- [ ] Hit `https://registry.modelcontextprotocol.io/v0.1/version` and
confirm `git_commit` matches `f5f40bd...`
- [ ] Spot-check the catalogue UI loads cleanly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The HTTP namespace-verification fetcher's `isBlockedIP` composed its
blocklist from Go stdlib's `Is*` helpers plus a manual CGNAT range. That
covers IPv4 cloud metadata, RFC1918, ULA, and link-local — but Go's
classification helpers don't recognise IPv6 prefix families that embed
or tunnel to arbitrary IPv4:
- 2002::/16 RFC 3056 6to4 — bits 16-47 are an arbitrary IPv4
- 64:ff9b::/96 RFC 6052 NAT64 well-known — low 32 bits are IPv4
- 64:ff9b:1::/48 RFC 8215 NAT64 local-use — same IPv4-embedding shape
- fec0::/10 RFC 3879 site-local (deprecated, still routed by
some stacks)
On hosts with 6to4 routing or a NAT64 next-hop (the default on
IPv6-only GKE node pools, AWS IPv6-only EC2, Azure IPv6 VMs with
NAT64, and many corporate DNS64/NAT64 networks), an attacker who
controls DNS for a publisher domain can cause the registry to dial
`169.254.169.254`, `10.0.0.0/8`, etc. via the IPv6 wrapper. Same
SSRF class as GHSA-56c3-vfp2-5qqj on n8n-mcp.
Define the four prefixes via a new `mustCIDR` helper (panic on
malformed CIDR at init so a typo can't fail-open silently) and iterate
them in `isBlockedIP` after the stdlib gates. Refactor the existing
CGNAT IIFE to use the same helper for consistency. IPv4-mapped IPv6
(::ffff:0:0/96) needs no special-casing: Go's `Is*` helpers honour the
`To4()` fast-path, so e.g. `::ffff:10.0.0.1` is already classified as
`IsPrivate`.
Adds 17 test cases to `TestIsBlockedIP` covering each new prefix
family, IPv4-mapped IPv6 sanity checks, and just-outside-the-range
positive controls (`2001::1`, `2003::1`, `64:ff9c::1`).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
`validateWebsiteURL` only checked that the URL parses, is absolute, and
uses the `https` scheme. It accepted literal `"`, `'`, `<`, `>`, and
ASCII space — none of which are valid in a URI per RFC 3986, and all of
which broke rendering when the value flowed into the catalogue UI's
`<a href="...">` template.
Add a `strings.IndexAny` check after the scheme check that rejects any
of these characters with a clear `website-url-invalid-characters` issue
that points at the offending byte position. Control characters (`\t`,
`\n`, `\r`) are also covered: they're caught one step earlier by Go's
`url.Parse`, but the bytes are listed in the rejection set so the
behaviour is explicit and survives any future relaxation of `url.Parse`.
Already-percent-encoded URLs (e.g. `?q=hello%20world`) continue to
validate cleanly.
Adds table-driven cases for `"`, `'`, `<>`, space, newline, and a
positive case for percent-encoded special characters.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The catalogue page interpolates publisher-supplied URL fields
(`server.repository.url`, `server.websiteUrl`) inside `href="..."`
attributes via `innerHTML`, escaping them with a
`textContent`→`innerHTML`
helper. Per the HTML5 fragment-serialisation algorithm, that round-trip
encodes only `&`, `<`, `>`, and U+00A0 inside text nodes — it does not
encode `"` or `'`. The helper is therefore safe in element-text
contexts (where it is used for `name`, `version`, `description`, etc.)
but unsafe inside an attribute value.
Add an attribute-safe `escapeAttr` helper that follows the OWASP
attribute-encoding rule (also encodes `"` and `'`) and use it for the
two `href` interpolations. Element-text usages keep the existing
`escapeHtml` and remain unchanged. A short comment on each helper
documents the contexts they cover so future fields are wired up
correctly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Summary
Follow-up to #1241. Two small tweaks to the `readBody` helper:
- **Rename `readBody` → `readErrorBody`.** The helper is only ever
called on the error path (after a non-2xx status check), where we want a
small string for diagnostics. The generic name made it look reusable on
the success path, where streaming JSON decoding is the right approach.
The new name pins the intended use down.
- **Cap the read with `io.LimitReader` (8 KiB).** Defense in depth —
error diagnostics never need more than a few KB, and we shouldn't buffer
an arbitrarily large body from an upstream just to format an error
message. 8 KiB is well above any realistic GitHub API or JWKS error
response.
No behavior change on the happy path. On the unhappy path, error
messages are now bounded.
## Test plan
- [x] `go build ./...`
- [x] `go test ./internal/api/handlers/v0/auth/...`
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The same pattern for reading an error response body appeared in three
places across the auth handlers:
- `internal/api/handlers/v0/auth/github_at.go` (twice)
- `internal/api/handlers/v0/auth/github_oidc.go` (once)
A shared `readBody` helper function added to `common.go` now handles
this in one place.
The `io` import is removed from both files since it is no longer used
directly there.
---------
Co-authored-by: Radoslav Dimitrov <radoslav@stacklok.com>
## Summary
Follow-up to #1238 (closes#988). Adds direct unit-test coverage for the
`claimMatches` helper, which was the actual change in #1238.
`claimMatches` and `toAnySlice` are unexported, so the tests live in
`oidc_internal_test.go` (`package auth`) — same pattern as
`http_internal_test.go`. Cases covered:
- scalar/scalar match and mismatch
- scalar actual against array expected (both directions of overlap)
- array actual against scalar expected
- **array/array** — pre-#1238 this combination panicked with `comparing
uncomparable type []interface {}`
- `[]string` typed slice (exercises the typed-slice branch of
`toAnySlice`, which `[]any` skips)
- non-string scalars (int, bool)
- empty actual array
Test values use single letters (`x`, `y`, `p`, `q`) rather than role
labels — only the relationships matter, and short tokens keep `goconst`
quiet.
## Test plan
- [x] `go test ./internal/api/handlers/v0/auth/...` — all 13 subtests
pass
- [x] `golangci-lint run ./internal/api/handlers/v0/auth/...` — no new
issues vs main
Closes#988. Direct `actualValue != expectedValue` fails when the token
claim is an array (groups, roles, scp, aud). Switch to a slice-aware
any-of overlap so OIDC list claims are validated correctly.
Bumps
[github.com/pulumi/pulumi/sdk/v3](https://github.com/pulumi/pulumi) from
3.233.0 to 3.234.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pulumi/pulumi/releases">github.com/pulumi/pulumi/sdk/v3's
releases</a>.</em></p>
<blockquote>
<h2>v3.234.0</h2>
<h2>3.234.0 (2026-05-01)</h2>
<h3>Features</h3>
<ul>
<li>
<p>[cli/cloud] Add <code>pulumi cloud api describe</code> for inspecting
the parameters, request
body, and response schema of any Pulumi Cloud API operation, with
text, markdown, and JSON output</p>
<p><a
href="https://redirect.github.com/pulumi/pulumi/pull/22770">#22770</a></p>
</li>
<li>
<p>[cli/cloud] Add <code>pulumi cloud api list</code> for browsing every
endpoint exposed by the Pulumi
Cloud OpenAPI spec, with table and JSON output</p>
<p><a
href="https://redirect.github.com/pulumi/pulumi/pull/22769">#22769</a></p>
</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>[engine] Revert changes to property path parsing that resulted in
errors for currently valid paths</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pulumi/pulumi/blob/master/CHANGELOG.md">github.com/pulumi/pulumi/sdk/v3's
changelog</a>.</em></p>
<blockquote>
<h2>3.234.0 (2026-05-01)</h2>
<h3>Features</h3>
<ul>
<li>
<p>[cli/cloud] Add <code>pulumi cloud api describe</code> for inspecting
the parameters, request
body, and response schema of any Pulumi Cloud API operation, with
text, markdown, and JSON output</p>
<p><a
href="https://redirect.github.com/pulumi/pulumi/pull/22770">#22770</a></p>
</li>
<li>
<p>[cli/cloud] Add <code>pulumi cloud api list</code> for browsing every
endpoint exposed by the Pulumi
Cloud OpenAPI spec, with table and JSON output</p>
<p><a
href="https://redirect.github.com/pulumi/pulumi/pull/22769">#22769</a></p>
</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>[engine] Revert changes to property path parsing that resulted in
errors for currently valid paths</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="e802ef2c5b"><code>e802ef2</code></a>
Revert "Tighten parsing on new property paths (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22695">#22695</a>)"
(<a
href="https://redirect.github.com/pulumi/pulumi/issues/22801">#22801</a>)</li>
<li><a
href="f5deaa1b20"><code>f5deaa1</code></a>
cli/cloud: add <code>pulumi cloud api describe</code> (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22770">#22770</a>)</li>
<li><a
href="bccf53d1fb"><code>bccf53d</code></a>
cli/cloud: add <code>pulumi cloud api list</code> (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22769">#22769</a>)</li>
<li><a
href="5575172e07"><code>5575172</code></a>
Changelog and go.mod updates for v3.233.0 (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22795">#22795</a>)</li>
<li><a
href="caf13d6d14"><code>caf13d6</code></a>
Cancel in-flight fuzz iterations when the 20s cap fires (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22725">#22725</a>)</li>
<li><a
href="324811c0a7"><code>324811c</code></a>
Freeze v2.233.0 (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22793">#22793</a>)</li>
<li>See full diff in <a
href="https://github.com/pulumi/pulumi/compare/v3.233.0...v3.234.0">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [github.com/caarlos0/env/v11](https://github.com/caarlos0/env)
from 11.4.0 to 11.4.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/caarlos0/env/releases">github.com/caarlos0/env/v11's
releases</a>.</em></p>
<blockquote>
<h2>v11.4.1</h2>
<h2>Changelog</h2>
<h3>Bug fixes</h3>
<ul>
<li>6daeb06ac7e3c9532a7eaa5768d45917393b7480: fix: use Key instead of
OwnKey in rawEnvVars to properly reference existing defaults in complex
structs (<a
href="https://redirect.github.com/caarlos0/env/issues/412">#412</a>) (<a
href="https://github.com/AndrewChubatiuk"><code>@AndrewChubatiuk</code></a>)</li>
</ul>
<h3>Documentation updates</h3>
<ul>
<li>1ff55e6c9733833ce75d62b345916a407dbe4158: docs: adaptive starchart
(<a href="https://redirect.github.com/caarlos0/env/issues/416">#416</a>)
(<a
href="https://github.com/alexandear"><code>@alexandear</code></a>)</li>
</ul>
<h3>Other work</h3>
<ul>
<li>cf4a9682420b025e44b4773fd7ee0be48bb68b2f: ci(deps): bump the actions
group with 3 updates (<a
href="https://redirect.github.com/caarlos0/env/issues/411">#411</a>) (<a
href="https://github.com/dependabot"><code>@dependabot</code></a>[bot])</li>
<li>33faf6f333c2c3dacef2991825f8e03960a2c0cb: ci(deps): bump the actions
group with 3 updates (<a
href="https://redirect.github.com/caarlos0/env/issues/417">#417</a>) (<a
href="https://github.com/dependabot"><code>@dependabot</code></a>[bot])</li>
<li>0cb635b62488f4d310809a82a8832cedc9aa94eb: ci(deps): bump the actions
group with 6 updates (<a
href="https://redirect.github.com/caarlos0/env/issues/415">#415</a>) (<a
href="https://github.com/dependabot"><code>@dependabot</code></a>[bot])</li>
<li>a72d89a8930fc800372a6a338a1acf33e5cc3a56: ci: update release config
(<a href="https://github.com/caarlos0"><code>@caarlos0</code></a>)</li>
</ul>
<hr />
<p><em>Released with <a href="https://goreleaser.com/pro">GoReleaser
Pro</a>!</em></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="a72d89a893"><code>a72d89a</code></a>
ci: update release config</li>
<li><a
href="6daeb06ac7"><code>6daeb06</code></a>
fix: use Key instead of OwnKey in rawEnvVars to properly reference
existing d...</li>
<li><a
href="33faf6f333"><code>33faf6f</code></a>
ci(deps): bump the actions group with 3 updates (<a
href="https://redirect.github.com/caarlos0/env/issues/417">#417</a>)</li>
<li><a
href="1ff55e6c97"><code>1ff55e6</code></a>
docs: adaptive starchart (<a
href="https://redirect.github.com/caarlos0/env/issues/416">#416</a>)</li>
<li><a
href="0cb635b624"><code>0cb635b</code></a>
ci(deps): bump the actions group with 6 updates (<a
href="https://redirect.github.com/caarlos0/env/issues/415">#415</a>)</li>
<li><a
href="cf4a968242"><code>cf4a968</code></a>
ci(deps): bump the actions group with 3 updates (<a
href="https://redirect.github.com/caarlos0/env/issues/411">#411</a>)</li>
<li>See full diff in <a
href="https://github.com/caarlos0/env/compare/v11.4.0...v11.4.1">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps
[github.com/pulumi/pulumi/sdk/v3](https://github.com/pulumi/pulumi) from
3.232.0 to 3.233.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pulumi/pulumi/releases">github.com/pulumi/pulumi/sdk/v3's
releases</a>.</em></p>
<blockquote>
<h2>v3.233.0</h2>
<h2>3.233.0 (2026-04-30)</h2>
<h3>Features</h3>
<ul>
<li>
<p>[auto/python] Expose the auto-generated Pulumi CLI interface as
<code>workspace.cli_api</code>
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22638">#22638</a></p>
</li>
<li>
<p>[cli] Add encrypted logging to ~/.pulumi/logs; use the
PULUMI_ENABLE_AUTOMATIC_LOGGING feature flag to turn it on
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22494">#22494</a></p>
</li>
<li>
<p>[cli] Implement the <code>filesystem__grep</code> and
<code>filesystem__content_replace</code> local tools
for <code>pulumi neo</code>. <code>grep</code> runs a regex search
across files in the project root
with an optional <code>include</code> glob filter and returns results in
<code>path:lineno: line</code>
form. <code>content_replace</code> performs a literal multi-file
search-and-replace with a
<code>file_pattern</code> glob and <code>dry_run</code> preview mode.
Both tools skip binary files,
hidden directories, and <code>node_modules</code>, and reject paths
outside the project
root. Their input schemas match the cloud-side tool definitions.</p>
<p><a
href="https://redirect.github.com/pulumi/pulumi/pull/22655">#22655</a></p>
</li>
<li>
<p>[cli] Add <code>pulumi_preview</code> and <code>pulumi_up</code> as
local tools for the experimental <code>pulumi neo</code>
agent. The Neo TUI renders a persistent bordered block for each
operation that
streams changed resources and diagnostics as the engine runs and
finalizes with a
summary of the op counts. Hidden behind PULUMI_EXPERIMENTAL.</p>
<p><a
href="https://redirect.github.com/pulumi/pulumi/pull/22697">#22697</a></p>
</li>
<li>
<p>[engine] Add <code>List</code> to the provider protocol and schema
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22693">#22693</a></p>
</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>
<p>[engine] Return a clear error when two installed plugins claim the
same default provider package name (for example, a native
<code>scaleway</code> provider alongside a
<code>terraform-provider</code> bridge parameterized as
<code>scaleway</code>) instead of panicking with "Should not have
seen an older plugin if sorting is correct!"
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22679">#22679</a></p>
</li>
<li>
<p>[programgen] Do not wrap a <code>call(...)</code> on a method whose
return type is marked plain in an Output. Previously
PCL bound every method call's return type as
<code>Output<T></code>, which caused downstream program-gen
to emit broken <code>.apply(...)</code>/<code>.ApplyT(...)</code>
traversals against plain struct returns (e.g.
methods with <code>liftSingleValueMethodReturns=true</code> or
<code>ReturnTypePlain=true</code>).</p>
<p><a
href="https://redirect.github.com/pulumi/pulumi/pull/22696">#22696</a></p>
</li>
<li>
<p>[backend/diy] When using a backend url containing creds (e.g.
PostgreSQL conn string), mask user:pass as in lock-related error
messages
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22701">#22701</a></p>
</li>
<li>
<p>[codegen/go] Generate unqualified <code>Provider</code> references
for the package's own provider resource. Previously
the Go codegen always emitted <code><pkg>.Provider</code> even
when the reference appeared inside <code><pkg></code></p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pulumi/pulumi/blob/master/CHANGELOG.md">github.com/pulumi/pulumi/sdk/v3's
changelog</a>.</em></p>
<blockquote>
<h2>3.233.0 (2026-04-30)</h2>
<h3>Features</h3>
<ul>
<li>
<p>[auto/python] Expose the auto-generated Pulumi CLI interface as
<code>workspace.cli_api</code>
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22638">#22638</a></p>
</li>
<li>
<p>[cli] Add encrypted logging to ~/.pulumi/logs; use the
PULUMI_ENABLE_AUTOMATIC_LOGGING feature flag to turn it on
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22494">#22494</a></p>
</li>
<li>
<p>[cli] Implement the <code>filesystem__grep</code> and
<code>filesystem__content_replace</code> local tools
for <code>pulumi neo</code>. <code>grep</code> runs a regex search
across files in the project root
with an optional <code>include</code> glob filter and returns results in
<code>path:lineno: line</code>
form. <code>content_replace</code> performs a literal multi-file
search-and-replace with a
<code>file_pattern</code> glob and <code>dry_run</code> preview mode.
Both tools skip binary files,
hidden directories, and <code>node_modules</code>, and reject paths
outside the project
root. Their input schemas match the cloud-side tool definitions.</p>
<p><a
href="https://redirect.github.com/pulumi/pulumi/pull/22655">#22655</a></p>
</li>
<li>
<p>[cli] Add <code>pulumi_preview</code> and <code>pulumi_up</code> as
local tools for the experimental <code>pulumi neo</code>
agent. The Neo TUI renders a persistent bordered block for each
operation that
streams changed resources and diagnostics as the engine runs and
finalizes with a
summary of the op counts. Hidden behind PULUMI_EXPERIMENTAL.</p>
<p><a
href="https://redirect.github.com/pulumi/pulumi/pull/22697">#22697</a></p>
</li>
<li>
<p>[engine] Add <code>List</code> to the provider protocol and schema
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22693">#22693</a></p>
</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>
<p>[engine] Return a clear error when two installed plugins claim the
same default provider package name (for example, a native
<code>scaleway</code> provider alongside a
<code>terraform-provider</code> bridge parameterized as
<code>scaleway</code>) instead of panicking with "Should not have
seen an older plugin if sorting is correct!"
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22679">#22679</a></p>
</li>
<li>
<p>[programgen] Do not wrap a <code>call(...)</code> on a method whose
return type is marked plain in an Output. Previously
PCL bound every method call's return type as
<code>Output<T></code>, which caused downstream program-gen
to emit broken <code>.apply(...)</code>/<code>.ApplyT(...)</code>
traversals against plain struct returns (e.g.
methods with <code>liftSingleValueMethodReturns=true</code> or
<code>ReturnTypePlain=true</code>).</p>
<p><a
href="https://redirect.github.com/pulumi/pulumi/pull/22696">#22696</a></p>
</li>
<li>
<p>[backend/diy] When using a backend url containing creds (e.g.
PostgreSQL conn string), mask user:pass as in lock-related error
messages
<a
href="https://redirect.github.com/pulumi/pulumi/pull/22701">#22701</a></p>
</li>
<li>
<p>[codegen/go] Generate unqualified <code>Provider</code> references
for the package's own provider resource. Previously
the Go codegen always emitted <code><pkg>.Provider</code> even
when the reference appeared inside <code><pkg></code>
itself, producing identifiers that would not compile. Affects generated
code for method return</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="fa313013d0"><code>fa31301</code></a>
don't stamp vcs information into binaries (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22788">#22788</a>)</li>
<li><a
href="17fd40453d"><code>17fd404</code></a>
double timeout in "does not hang" test (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22789">#22789</a>)</li>
<li><a
href="eb6e31d841"><code>eb6e31d</code></a>
split tests module on macos further (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22790">#22790</a>)</li>
<li><a
href="94dbe6401b"><code>94dbe64</code></a>
Remove runInStack from run-policy-pack (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22783">#22783</a>)</li>
<li><a
href="a35ec7e9d5"><code>a35ec7e</code></a>
retry pip install a few times (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22785">#22785</a>)</li>
<li><a
href="7a4beeaa44"><code>7a4beea</code></a>
Reject schemas with duplicate tokens after applying
<code>moduleFormat</code> (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22765">#22765</a>)</li>
<li><a
href="0b914cee46"><code>0b914ce</code></a>
unflake TestNodejsComponentProviderRun (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22782">#22782</a>)</li>
<li><a
href="5cd1646706"><code>5cd1646</code></a>
start logging encrypted logs for all pulumi commands (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22494">#22494</a>)</li>
<li><a
href="a81ef07c09"><code>a81ef07</code></a>
pin more plugin versions in integration tests (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22758">#22758</a>)</li>
<li><a
href="0d2b8bf114"><code>0d2b8bf</code></a>
Update list doc comment (<a
href="https://redirect.github.com/pulumi/pulumi/issues/22777">#22777</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/pulumi/pulumi/compare/v3.232.0...v3.233.0">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
## Summary
Follow-up to #1229. Three small doc additions so the new audience
requirement is discoverable without reading the source:
- `.env.example` lists `MCP_REGISTRY_GITHUB_OIDC_AUDIENCE` alongside the
other registry env vars, with a note that the value must match the
scheme+host that publishers pass via `--registry`.
- The publisher CLI reference (`docs/reference/cli/commands.md`)
explains that the CLI derives the audience from `--registry` and that
self-hosters must set the matching env var on the registry side.
- The GitHub Actions troubleshooting table
(`docs/modelcontextprotocol-io/github-actions.mdx`) maps the new
`invalid audience` error to the user-facing fix (upgrade
`mcp-publisher`).
No code changes — docs only.
## Test plan
- [ ] CI green (markdown lint / link checks if any)
- [ ] Eyeball-render the troubleshooting table on the
modelcontextprotocol.io preview to confirm the new row formats correctly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## What this does
The publisher CLI now derives the OIDC audience to request from the
`--registry` URL instead of using a fixed constant, and the server
validates the token's `aud` claim against a new per-deployment env var
(`MCP_REGISTRY_GITHUB_OIDC_AUDIENCE`).
Production sets this env var to
`https://registry.modelcontextprotocol.io` (and per-environment URL
elsewhere), so the deployment only accepts tokens that were requested
for it.
## Compatibility
This is a breaking change for older `mcp-publisher` binaries that still
request the legacy hardcoded audience. After this rolls to a deployment,
users on old `mcp-publisher` will see a clear `invalid audience:
expected …, got […]` error and need to upgrade. Users following the
documented `releases/latest` install pattern get the new binary
automatically.
## Test plan
- [ ] CI green
- [ ] Run a synthetic publish from a real GitHub Actions workflow
against staging after deploy
- [ ] Confirm an older `mcp-publisher` against the same staging deploy
returns the expected `invalid audience` error
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>