Repository navigation
Conversation
Codex Review Summary: ✅ CompletedThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
@jokemanfire is on triage rotation this week and is the reviewer for this one. Labels come from the PR labeler. Please review the change. Automated triage. Labels are a first pass and the assigned maintainer has the final say. |
e28c827 to
d2ccd7e
Compare
…ete only when declared Signed-off-by: wangshun <[email protected]>
d2ccd7e to
f649888
Compare
jokemanfire
left a comment
There was a problem hiding this comment.
Verified at a4b6647 (base f852ec0) by running a probe pair, not by reading the diff. Three asks, all small; none is about correctness of the two hunks you wrote.
Verification
Probe: serve_directly on a tokio::io::duplex(4096) pair at ProtocolVersion::V_2026_07_28, server = ServerCapabilities::builder().enable_tools().build() and no method overrides; same probe binary run on upstream/main and on your head.
| call | f852ec0 (main) |
a4b6647 (head) |
|---|---|---|
prompts/list |
Ok |
Err -32601: prompts/list |
completion/complete |
Ok |
Err -32601: completion/complete |
resources/list |
Ok |
Ok |
resources/templates/list |
Ok |
Ok |
tools/list |
Ok |
Ok |
With enable_prompts().enable_completions() declared, both calls still return Ok (completion values=[]), so the "keep the empty success when advertised" half works too. CI at a4b6647 is 24/24 green.
Your regression test is real: crates/rmcp/tests/test_with_js.rs is executed by the Run Tests (no local feature) job (cargo test -p rmcp --features <all except local>), not by Run Tests. Locally, cargo test -p rmcp --all-features --test test_with_js compiles the file to 0 tests because of #![cfg(not(feature = "local"))] — worth knowing before anyone concludes the JS check passed from a --all-features run.
No macro regression: #[prompt_handler] injects its own list_prompts and a get_info with prompts enabled (crates/rmcp-macros/src/prompt_handler.rs:57, :110), so the new trait default only affects handlers that rely on it.
Asks
-
resources/listandresources/templates/listkeep the same hole. Rows 3-4 above: a server that declares noresourcescapability still answers both with an empty success, whileread_resource,get_prompt,set_levelandsubscribealready return-32601from their defaults. Issue #1445 calls this out explicitly ("list_resources,list_resource_templatesandlist_toolshave the sameOk(default)defaults"). Gating the two resource defaults is two lines and the same shape as what you wrote; if you would rather keep this PR narrow, please open the follow-up and say so in the body so it does not get lost. -
Pin the behaviour with a Rust test. Right now the only regression coverage is the npm-backed JS file — it is a genuine check (it does run in CI), but it costs a node install and disappears entirely under
--all-features. A duplex test likecrates/rmcp/tests/test_handler_cache_hints.rs:99-130can assert both directions cheaply: tools-only server →-32601for both methods, declared server →Ok. -
Say the behaviour change out loud. Servers that never declared
prompts/completionsbut relied on the default empty success will start receiving errors from the next release. A line in the PR body and in the release notes (seeVERSIONING.md) is enough; it is a fix, not an API break, but clients of such servers should not be surprised.
I am not approving until these are answered — ask 1 is the one I would like to see resolved in this PR.
|
@jokemanfire Thanks for the careful before/after probe and for clarifying which CI configuration actually runs the JS regression test. I agree with all three asks.
I haven't made those follow-up changes yet; I'll update this thread once the changes and checks are ready for another review. |
|
@jokemanfire Follow-up pushed in
The latest GitHub CI is still pending; I'd appreciate another look once it finishes. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 292142dccb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
292142d to
2efd7c0
Compare
|
@jokemanfire Final follow-up: GitHub CI is now green, including |
SIDDARTHAREDDY8
left a comment
There was a problem hiding this comment.
I read the changes in crates/rmcp/src/handler/server.rs and the new test_default_list_capabilities.rs, plus the fixture updates. Two checks and one question:
-
This completes an existing pattern rather than inventing one: get_prompt, call_tool, read_resource, subscribe and set_level already returned method_not_found from their defaults, so gating the five list/complete defaults on the advertised capability is consistent with the rest of server.rs.
-
The gate lives only in the default implementations, so a server that overrides list_tools (or the other methods) is unaffected even if it does not advertise the capability. The CHANGELOG entry says "default ... handlers", which matches, but it is worth confirming that is the intended scope, since the behavior-change note could be read as broader.
-
get_info() is now consulted on every default list call. If a handler builds its ServerConfig dynamically from runtime state, the capability seen here could disagree with what was advertised during initialize. Is get_info() expected to be cheap and stable per handler? If so, a line in the trait docs saying so would pin the assumption down.
The test matrix (no capabilities, tools only, all enabled) covers the combinations well, and the fixture updates in the other test files show the blast radius was walked through.
Preserve the default-method compatibility note under Unreleased after the v3.10.0 release. Document the stability and cost expectations for get_info capabilities used by request-time default handlers.
|
@SIDDARTHAREDDY8 Thanks for the thoughtful review. Yes, the scope is intentional: these checks apply only to the
That commit also merges the latest |
jokemanfire
left a comment
There was a problem hiding this comment.
All three asks from my review at a4b6647 are resolved at b1305af, and I re-ran the gates rather than reading the diff.
Verification at b1305af (base 53e64a9, i.e. after merging main)
test_default_list_capabilities(new): 1 passed. It covers capabilities{},{tools}and{tools,resources,prompts,completions}against all five methods, so the two resource defaults you gated in2efd7c0are pinned, not just the original two.test_handler_cache_hints8 passed,test_client_lifecycle_modes16 passed,test_stateless_server_requests4 passed,test_streamable_http_session_store4 passed,test_streamable_http_stale_session4 passed,test_discover_http_client_startup4 passed,test_tool_macros16 passed,test_prompt_macros8 passed (featuresclient server reqwest transport-streamable-http-server transport-streamable-http-client-reqwest, plusmacrosfor the macro binaries). Total 65 passed, 0 failed.cargo fmt --checkclean.
Ask 3 is satisfied by the [Unreleased] / Fixed entry, which names the five methods and the behavior change explicitly, and the get_info doc note covers the "defaults call get_info() per request" contract. The JS regression is not run locally (node install); CI's Run Tests (no local feature) job covers it, as established in the previous round.
One non-blocking observation, no action needed: the default handlers now call get_info() on every list_*/complete request, so an implementation whose get_info is expensive or allocates a fresh ServerConfig pays that per call. The new trait docs say it should be cheap and consistent, which is the right trade-off for keeping the trait surface unchanged.
LGTM from me on the code and the evidence.
| ### Fixed | ||
|
|
||
| - Default `prompts/list`, `completion/complete`, `resources/list`, | ||
| `resources/templates/list`, and `tools/list` handlers now return JSON-RPC | ||
| `-32601` (method not found) when their capability is not advertised. Servers | ||
| that relied on the previous empty success responses without declaring the | ||
| capability will see a behavior change; advertise the capability to retain | ||
| the empty default result. | ||
|
|
There was a problem hiding this comment.
We shouldn't write the changelog manually. It's generated by the release automation.
There was a problem hiding this comment.
Agreed, thanks for the clarification. I removed the manually added Unreleased changelog entry in e4684ee. The release automation can generate it instead; the implementation and regression tests remain unchanged.
Fixes #1445
Why
The default
ServerHandlerimplementations forprompts/list,completion/complete,resources/list,resources/templates/list, andtools/listreturned successful empty results even whenget_info()did not advertise the corresponding capability. This can mislead capability discovery and conformance clients.Change
-32601(method not found) when the corresponding capability is absent fromget_info().--all-features.crates/rmcp/CHANGELOG.md.Compatibility note
This intentionally changes observable wire behavior: servers that do not advertise
prompts,completions,resources, ortoolsbut previously relied on the corresponding default empty success response will now return-32601for those methods. To retain an empty default result, advertise the relevant capability. No Rust trait signatures or public types change; this is a protocol-conformance bug fix.Verification
client,serverand with--all-features.cargo fmt --all -- --check,node --check, andgit diff --checkpassed.localmatrix and Commitlint) passed on2efd7c0.The original regression was reproduced on
f852ec0e9281(fail before / pass after the initial fix).AI assistance: OpenCode and oss-scout generated and verified the initial patch; ChatGPT helped review, extend the fix, add regression coverage, and verify the follow-up.