Skip to content

feat: replace custom mcp-types crate with equivalents from rmcp#10349

Merged
bolinfest merged 1 commit intomainfrom
pr10349
Feb 3, 2026
Merged

feat: replace custom mcp-types crate with equivalents from rmcp#10349
bolinfest merged 1 commit intomainfrom
pr10349

Conversation

@bolinfest
Copy link
Collaborator

@bolinfest bolinfest commented Feb 2, 2026

We started working with MCP in Codex before https://crates.io/crates/rmcp was mature, so we had our own crate for MCP types that was generated from the MCP schema:

https://github.com/openai/codex/blob/8b95d3e082376f4cb23e92641705a22afb28a9da/codex-rs/mcp-types/README.md

Now that rmcp is more mature, it makes more sense to use their MCP types in Rust, as they handle details (like the _meta field) that our custom version ignored. Though one advantage that our custom types had is that our generated types implemented JsonSchema and ts_rs::TS, whereas the types in rmcp do not. As such, part of the work of this PR is leveraging the adapters between rmcp types and the serializable types that are API for us (app server and MCP) introduced in #10356.

Note this PR results in a number of changes to codex-rs/app-server-protocol/schema, which merit special attention during review. We must ensure that these changes are still backwards-compatible, which is possible because we have:

- export type CallToolResult = { content: Array<ContentBlock>, isError?: boolean, structuredContent?: JsonValue, };
+ export type CallToolResult = { content: Array<JsonValue>, structuredContent?: JsonValue, isError?: boolean, _meta?: JsonValue, };

so ContentBlock has been replaced with the more general JsonValue. Note that ContentBlock was defined as:

export type ContentBlock = TextContent | ImageContent | AudioContent | ResourceLink | EmbeddedResource;

so the deletion of those individual variants should not be a cause of great concern.

Similarly, we have the following change in codex-rs/app-server-protocol/schema/typescript/Tool.ts:

- export type Tool = { annotations?: ToolAnnotations, description?: string, inputSchema: ToolInputSchema, name: string, outputSchema?: ToolOutputSchema, title?: string, };
+ export type Tool = { name: string, title?: string, description?: string, inputSchema: JsonValue, outputSchema?: JsonValue, annotations?: JsonValue, icons?: Array<JsonValue>, _meta?: JsonValue, };

so:

  • annotations?: ToolAnnotations ➡️ JsonValue
  • inputSchema: ToolInputSchema ➡️ JsonValue
  • outputSchema?: ToolOutputSchema ➡️ JsonValue

and two new fields: icons?: Array<JsonValue>, _meta?: JsonValue


Stack created with Sapling. Best reviewed with ReviewStack.

@@ -0,0 +1,119 @@
use std::collections::HashMap;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we defer these refactoring to a later PR so the diffs are just about replacing the mcp types?

const MCP_TOOL_NAME_PREFIX: &str = "mcp";
const MCP_TOOL_NAME_DELIMITER: &str = "__";
pub(crate) const CODEX_APPS_MCP_SERVER_NAME: &str = "codex_apps";
const CODEX_CONNECTORS_TOKEN_ENV_VAR: &str = "CODEX_CONNECTORS_TOKEN";
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here, can we defer these refactoring to a later PR so the diffs are cleaner?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah, sorry about that. Codex and I had a misunderstanding: I'll back this out!

bolinfest added a commit that referenced this pull request Feb 2, 2026
Currently, types from our custom `mcp-types` crate are part of some of
our APIs:


https://github.com/openai/codex/blob/03fcd12e77fedf4fa327af27e2e476e1ebc5f651/codex-rs/app-server-protocol/src/protocol/v2.rs#L43-L46

To eliminate this crate in #10349 by switching to `rmcp`, we need our
own wrappers for the `rmcp` types that we can use in our API, which is
what this PR does.

Note this PR introduces the new API types, but we do not make use of
them until #10349.





---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/10356).
* #10357
* #10349
* __->__ #10356
Base automatically changed from pr10356 to main February 2, 2026 16:41
Copy link
Collaborator

@owenlin0 owenlin0 left a comment

Choose a reason for hiding this comment

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

I'll give a heads up to our partners that this is coming, based on the PR description it looks like updating their clients hopefully won't be too arduous

// this crate exports JSON schema + TS types (`schemars`/`ts-rs`), and the rmcp model types
// aren't set up to be schema/TS friendly (and would introduce heavier coupling to rmcp's Rust
// representations). Using `JsonValue` keeps the payload wire-shaped and easy to export.
pub content: Vec<JsonValue>,
Copy link
Collaborator

Choose a reason for hiding this comment

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

very helpful, thanks!

@bolinfest bolinfest force-pushed the pr10349 branch 4 times, most recently from 99abcc3 to b1bfee9 Compare February 2, 2026 19:16
@mzeng-openai
Copy link
Contributor

LFG!

@bolinfest bolinfest merged commit 66447d5 into main Feb 3, 2026
62 of 64 checks passed
@bolinfest bolinfest deleted the pr10349 branch February 3, 2026 01:41
@github-actions github-actions bot locked and limited conversation to collaborators Feb 3, 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.

3 participants