Skip to content

Conversation

@bolinfest
Copy link
Collaborator

@bolinfest bolinfest commented Dec 16, 2025

#580 and #556 introduced support for custom notifications,
so this PR takes the next logical step and adds support for custom requests:

  • Introduces CustomRequest and CustomResult model types, wires them into the client/server
    request and result unions, and allows ClientRequest::method() to return the dynamic method
    name.
  • Implements serde and meta handling for CustomRequest so _meta is carried through
    extensions; adds default on_custom_request handlers that return METHOD_NOT_FOUND unless
    overridden.
  • Updates JSON schema fixtures to include the new request/result shapes and EmptyObject
    strictness.
  • Adds tests for custom request roundtrips and end-to-end client↔server handling.
  • Focused integration test in crates/rmcp/tests/test_custom_request.rs.

For additional testing, I used this locally to update Codex to use a custom
request instead of a custom notification so that it gets an "ack" from the MCP
server to ensure it has processed the update before sending more messages:
openai/codex#8142.

@github-actions github-actions bot added T-test Testing related changes T-config Configuration file changes T-core Core library changes T-handler Handler implementation changes T-model Model/data structure changes labels Dec 16, 2025
@bolinfest bolinfest changed the title # feat: add support for custom requests feat: add support for custom requests Dec 16, 2025
@bolinfest bolinfest force-pushed the pr590 branch 4 times, most recently from 2326775 to 5e1ebb1 Compare December 16, 2025 22:04
modelcontextprotocol#580 and modelcontextprotocol#556 introduced support for custom notifications,
so this PR takes the next logical step and adds support for custom requests:

- Introduces `CustomRequest` and `CustomResult` model types, wires them into the client/server
  request and result unions, and allows `ClientRequest::method()` to return the dynamic method
  name.
- Implements serde and meta handling for `CustomRequest` so `_meta` is carried through
  extensions; adds default `on_custom_request` handlers that return `METHOD_NOT_FOUND` unless
  overridden.
- Updates JSON schema fixtures to include the new request/result shapes and `EmptyObject`
  strictness.
- Adds tests for custom request roundtrips and end-to-end client↔server handling.
- Focused integration test in `crates/rmcp/tests/test_custom_request.rs`.

For additional testing, I used this locally to update Codex to use a custom
request instead of a custom notification so that it gets an "ack" from the MCP
server to ensure it has processed the update before sending more messages:
openai/codex#8142.
@alexhancock alexhancock merged commit e0faf1e into modelcontextprotocol:main Dec 18, 2025
11 checks passed
@github-actions github-actions bot mentioned this pull request Dec 16, 2025
bolinfest added a commit to openai/codex that referenced this pull request Dec 18, 2025
Version `0.12.0` includes
modelcontextprotocol/rust-sdk#590, which I will
use in #8142.

Changes:

- `rmcp::model::CustomClientNotification` was renamed to
`rmcp::model::CustomNotification`
- a bunch of types have a `meta` field now, but it is `Option`, so I
added `meta: None` to a bunch of things
bolinfest added a commit to openai/codex that referenced this pull request Dec 18, 2025
…st (#8142)

Historically, `accept_elicitation_for_prompt_rule()` was flaky because
we were using a notification to update the sandbox followed by a `shell`
tool request that we expected to be subject to the new sandbox config,
but because [rmcp](https://crates.io/crates/rmcp) MCP servers delegate
each incoming message to a new Tokio task, messages are not guaranteed
to be processed in order, so sometimes the `shell` tool call would run
before the notification was processed.

Prior to this PR, we relied on a generous `sleep()` between the
notification and the request to reduce the change of the test flaking
out.

This PR implements a proper fix, which is to use a _request_ instead of
a notification for the sandbox update so that we can wait for the
response to the sandbox request before sending the request to the
`shell` tool call. Previously, `rmcp` did not support custom requests,
but I fixed that in
modelcontextprotocol/rust-sdk#590, which made it
into the `0.12.0` release (see #8288).

This PR updates `shell-tool-mcp` to expect
`"codex/sandbox-state/update"` as a _request_ instead of a notification
and sends the appropriate ack. Note this behavior is tied to our custom
`codex/sandbox-state` capability, which Codex honors as an MCP client,
which is why `core/src/mcp_connection_manager.rs` had to be updated as
part of this PR, as well.

This PR also updates the docs at `shell-tool-mcp/README.md`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-config Configuration file changes T-core Core library changes T-handler Handler implementation changes T-model Model/data structure changes T-test Testing related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants