Skip to content

[1/4] Add executor HTTP request protocol#18581

Merged
aibrahim-oai merged 9 commits intomainfrom
dev/remote-mcp-http-protocol-full-ci
Apr 21, 2026
Merged

[1/4] Add executor HTTP request protocol#18581
aibrahim-oai merged 9 commits intomainfrom
dev/remote-mcp-http-protocol-full-ci

Conversation

@aibrahim-oai
Copy link
Copy Markdown
Collaborator

@aibrahim-oai aibrahim-oai commented Apr 19, 2026

Why

Remote streamable HTTP MCP needs a transport-shaped executor primitive before the MCP client can move network I/O to the executor. This layer keeps the executor unaware of MCP and gives later PRs an ordered streaming surface for response bodies.

What

  • Add typed http/request and http/request/bodyDelta protocol payloads.
  • Add executor client helpers for buffered and streamed HTTP responses.
  • Route body-delta notifications to request-scoped streams with sequence validation and cleanup when a stream finishes or is dropped.
  • Document the new protocol constants, transport structs, public client methods, body-stream lifecycle, and request-scoped routing helpers.
  • Add in-memory JSON-RPC client coverage for streamed HTTP response-body notifications, with comments spelling out what the test proves and each setup/exercise/assert phase.

Stack

  1. [1/4] Add executor HTTP request protocol #18581 protocol
  2. [2/4] Implement executor HTTP request runner #18582 runner
  3. [3/4] Add executor-backed RMCP HTTP client #18583 RMCP client
  4. [4/4] Honor Streamable HTTP MCP placement #18584 manager wiring and local/remote coverage

Verification

  • just fmt
  • cargo check -p codex-exec-server -p codex-rmcp-client --tests
  • cargo check -p codex-core --test all compile-only
  • git diff --check
  • Online full CI is running from the full-ci branch, including the remote Rust test job.

Co-authored-by: Codex noreply@openai.com

@aibrahim-oai
Copy link
Copy Markdown
Collaborator Author

aibrahim-oai commented Apr 19, 2026

Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

async fn fail_all_sessions(inner: &Arc<Inner>, message: String) {
let sessions = inner.take_all_sessions().await;
for (_, session) in sessions {
session.set_failure(message.clone()).await;
}

P1 Badge Clear HTTP stream routes when transport disconnects

fail_all_sessions only drains process sessions. After a disconnect, http_body_streams still holds each stream Sender, so HttpResponseBodyStream::recv() may wait forever because the channel never closes and no more deltas can arrive. It also leaves stale request_id registrations in memory until the whole client is dropped.

ℹ️ 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".

Comment thread codex-rs/exec-server/src/client.rs Outdated
@aibrahim-oai aibrahim-oai force-pushed the dev/remote-mcp-http-protocol-full-ci branch from d0f4fc9 to 1fc4cd7 Compare April 19, 2026 18:38
@aibrahim-oai aibrahim-oai changed the title Add executor HTTP request protocol [1/4] Add executor HTTP request protocol Apr 19, 2026
Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

async fn fail_all_sessions(inner: &Arc<Inner>, message: String) {
let sessions = inner.take_all_sessions().await;
for (_, session) in sessions {
session.set_failure(message.clone()).await;
}
}

P1 Badge Close HTTP body streams when transport disconnects

fail_all_sessions only drains process sessions and never clears http_body_streams. On RpcClientEvent::Disconnected or notification-handler failure, each stream keeps its mpsc::Sender alive, so HttpResponseBodyStream::recv() can block forever on rx.recv() instead of terminating when the transport dies. This can hang callers waiting for streamed HTTP bodies.

ℹ️ 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".

@aibrahim-oai aibrahim-oai force-pushed the dev/remote-mcp-http-protocol-full-ci branch from 1fc4cd7 to 5b3829a Compare April 19, 2026 18:48
Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

async fn fail_all_sessions(inner: &Arc<Inner>, message: String) {
let sessions = inner.take_all_sessions().await;
for (_, session) in sessions {
session.set_failure(message.clone()).await;
}

P1 Badge Close HTTP body routes on disconnect

When the RPC transport disconnects, fail_all_sessions only tears down process sessions and never touches http_body_streams. Active HttpResponseBodyStream receivers can then block forever in recv() because their sender is still retained in the routing map but no more notifications will arrive. Mid-stream network drops should terminate these streams with an error instead of hanging.

ℹ️ 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".

Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

RpcClientEvent::Disconnected { reason } => {
if let Some(inner) = weak.upgrade() {
fail_all_sessions(&inner, disconnected_message(reason.as_deref()))
.await;
}
return;

P1 Badge Close HTTP streams when the RPC transport disconnects

connect handles RpcClientEvent::Disconnected by failing process sessions and returning, but it never clears inner.http_body_streams. Those retained senders keep each HttpResponseBodyStream channel open, so recv() can block forever after transport loss instead of terminating with an error/EOF.

ℹ️ 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".

@aibrahim-oai aibrahim-oai force-pushed the dev/remote-mcp-http-protocol-full-ci branch from 5b3829a to 53977b8 Compare April 19, 2026 18:57
Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

RpcClientEvent::Disconnected { reason } => {
if let Some(inner) = weak.upgrade() {
fail_all_sessions(&inner, disconnected_message(reason.as_deref()))
.await;
}
return;

P1 Badge Fail active HTTP body streams when transport disconnects

Handle RpcClientEvent::Disconnected by failing process sessions only. It never closes or errors http_body_streams, so each stream's sender remains in the routing map. HttpResponseBodyStream::recv() then awaits forever after a transport drop, leaving callers stuck mid-response with no EOF/error.

ℹ️ 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".

@aibrahim-oai aibrahim-oai force-pushed the dev/remote-mcp-http-protocol-full-ci branch from 53977b8 to 8edc173 Compare April 19, 2026 19:07
Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8edc1730a8

ℹ️ 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".

Comment thread codex-rs/exec-server/src/client.rs Outdated
@aibrahim-oai aibrahim-oai force-pushed the dev/remote-mcp-http-protocol-full-ci branch from 8edc173 to 1a9358f Compare April 19, 2026 19:15
Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1a9358ff3f

ℹ️ 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".

Comment thread codex-rs/exec-server/src/client.rs Outdated
Comment thread codex-rs/exec-server/src/client.rs Outdated
@aibrahim-oai aibrahim-oai force-pushed the dev/remote-mcp-http-protocol-full-ci branch 2 times, most recently from 3018783 to c3159bc Compare April 20, 2026 15:45
Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c3159bc7a2

ℹ️ 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".

Comment thread codex-rs/exec-server/src/client.rs Outdated
@aibrahim-oai aibrahim-oai force-pushed the dev/remote-mcp-http-protocol-full-ci branch from c3159bc to 888b4d7 Compare April 20, 2026 15:52
Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 888b4d7bc6

ℹ️ 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".

Comment thread codex-rs/exec-server/src/client.rs Outdated
@aibrahim-oai aibrahim-oai force-pushed the dev/remote-mcp-http-protocol-full-ci branch 8 times, most recently from 26b3c57 to 657aee6 Compare April 20, 2026 18:26
@aibrahim-oai aibrahim-oai force-pushed the dev/remote-mcp-http-protocol-full-ci branch 3 times, most recently from d94e96f to fdbc9d9 Compare April 20, 2026 19:11
Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fdbc9d9c78

ℹ️ 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".

serde_json::from_value(params.unwrap_or(Value::Null))?;
// Unknown request ids are ignored intentionally: a consumer may have
// dropped its body stream after receiving the headers.
if let Some(route) = inner.get_http_body_stream(&params.request_id) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Isolate stream routes from reused request IDs

handle_http_body_delta_notification routes frames only by request_id. After a stream is dropped/canceled, that ID is removed and can be reused immediately, but no cancellation is sent upstream. Late bodyDelta frames from the old request can then be delivered into the new stream with the same ID, corrupting bytes or causing spurious seq failures.

Useful? React with 👍 / 👎.

@aibrahim-oai aibrahim-oai force-pushed the dev/remote-mcp-http-protocol-full-ci branch from fdbc9d9 to 0519903 Compare April 20, 2026 19:27
Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0519903bcd

ℹ️ 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".

let request_id = params.request_id.clone();
let terminal_delta = params.done || params.error.is_some();
match route.try_send(params) {
Some(Ok(())) => {}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove route after queuing a terminal body delta

handle_http_body_delta_notification does nothing on Some(Ok(())), even when terminal_delta is true. If the consumer drops before reading that queued terminal frame, Drop changes the route to Draining; since terminal has already arrived, no later notification removes it. The request id can remain permanently reserved.

Useful? React with 👍 / 👎.

@aibrahim-oai aibrahim-oai force-pushed the dev/remote-mcp-http-protocol-full-ci branch 7 times, most recently from c58360f to a0fc08c Compare April 21, 2026 00:36
Add typed http/request protocol structs plus client-side response-body stream routing for executor HTTP calls. This keeps later remote MCP HTTP work on a request-scoped transport surface without exposing MCP semantics to the executor.

Co-authored-by: Codex <noreply@openai.com>
@aibrahim-oai aibrahim-oai force-pushed the dev/remote-mcp-http-protocol-full-ci branch from a0fc08c to 0b2d771 Compare April 21, 2026 00:41
aibrahim-oai and others added 3 commits April 20, 2026 18:11
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
aibrahim-oai and others added 4 commits April 20, 2026 18:20
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Co-authored-by: Codex <noreply@openai.com>
Copy link
Copy Markdown
Contributor

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 59069ca8e6

ℹ️ 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".

// because they share the same connection-global notification channel as
// process output. Keep the routing table local to the client so higher
// layers can consume body chunks like a normal byte stream.
http_body_streams: ArcSwap<HashMap<String, mpsc::Sender<HttpRequestBodyDeltaNotification>>>,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add missing imports for HTTP stream route types

This commit does not compile: Inner.http_body_streams uses mpsc::Sender<HttpRequestBodyDeltaNotification> but neither tokio::sync::mpsc nor HttpRequestBodyDeltaNotification is imported in client.rs. A clean cargo check -p codex-exec-server --lib at this revision fails with unresolved-name errors, so the change is not buildable.

Useful? React with 👍 / 👎.

Comment on lines +219 to +225
let _ = tx.try_send(HttpRequestBodyDeltaNotification {
request_id,
seq: 1,
delta: Vec::new().into(),
done: true,
error: Some(message.clone()),
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Propagate disconnect errors when stream buffer is full

In fail_all_http_body_streams, terminal error frames are sent with tx.try_send(...) and the result is ignored. When a body stream buffer is already full, that error frame is dropped; once queued chunks drain, recv() sees channel close as Ok(None). A transport disconnect can therefore be observed as clean EOF with truncated data.

Useful? React with 👍 / 👎.

Co-authored-by: Codex <noreply@openai.com>
@aibrahim-oai aibrahim-oai enabled auto-merge (squash) April 21, 2026 02:06
@aibrahim-oai aibrahim-oai merged commit d6af7a6 into main Apr 21, 2026
60 of 74 checks passed
@aibrahim-oai aibrahim-oai deleted the dev/remote-mcp-http-protocol-full-ci branch April 21, 2026 02:21
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 21, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants