OpenAI quietly published openai/mcp-extensions on September 29. It is an Apache-2.0 repository with a specification, a TypeScript SDK (@openai/mcp-extensions) and a Python SDK (openai-mcp-extensions), currently at 0.1.0. The one-line pitch from the README: build plugins that feel like native, first-class features of ChatGPT. The repo sits at roughly 740 stars four days in, which tells you the developer attention is real but the ecosystem is not settled yet.
I spent an evening reading the spec end to end, because this touches the question I care about most: where does your agent tooling config stop being portable. Here is what is actually in there, and what it costs you.
What shipped this week
The package extends MCP, and the draft MCP Apps spec, with ChatGPT-specific capabilities: sidebar entrypoints, thread tabs, custom file viewers, composer at-mentions, structured settings, richer forms, and a bidirectional model-app context channel. The platform support table in the spec lists 13 features.
None of this is a new protocol. It all rides on top of MCP's existing extension points, specifically _meta keys and namespaced methods. That design decision is the whole story, and I will come back to it.
Three entrypoints, one _meta key
Any MCP App can define up to three entrypoints: a global one in the primary sidebar, a thread one as a content tab inside a conversation, and a file one that fires when a user opens a matching file type. You register them in the tool's metadata:
const toolMetadata = {
ui: { resourceUri: "ui://parts/library" },
"openai/ui": {
entrypoints: [{ type: "global" }],
}
} satisfies OpenAIUiToolMetadata;
That is the entire registration surface. The spec is unusually concrete about the small things too: entrypoint icons should be monochrome SVGs, 20x20px viewport, 1.33px strokes, using currentColor so they follow the user's theme. Someone shipped plugins before writing this.
The file boundary is worth copying
The file extension entrypoint is the most interesting part of the spec, for a reason that has nothing to do with ChatGPT. MCP Apps execute untrusted JavaScript, so ChatGPT never hands a raw filesystem path to the app. The app gets an opaque resourceUri. Resource reads and subscriptions are intercepted and handled by the host.
When the app calls a tool on its own MCP server, the host intercepts that call too and amends it with _meta["openai/resource"].path, the absolute path, but only on the server side. The app still only knows the opaque URI unless the server explicitly decides to pass the path back for a trusted app.
That is a clean security boundary: untrusted UI code sees handles, trusted server code sees paths. If you build agent tooling that touches files, this split is worth stealing regardless of whether you ever touch ChatGPT.
Writes go through ETags
MCP resources are read-only by tradition. The file entrypoint adds openai/resources/write, with three guardrails: the app may only write the exact resourceUri that opened the entrypoint, only if the read came back with writable: true, and if you pass ifMatch, the write only lands when the ETag still matches the latest value. That is optimistic concurrency for file editors inside a chat app. It is a small API but it answers the question every editor builder asks first.
The platform matrix has desktop-shaped holes
The support table is honest about where features actually work at launch. File entrypoints, local file opening, file resources, and composer at-mentions are Desktop-only. The web column means the ChatGPT Work browser, and classic ChatGPT is excluded entirely. Android gets no deep links, and form elicitation is absent on both mobile platforms.
Read that again from a product angle: if your plugin's core value is a custom viewer for .stl or .ipynb files, your audience is ChatGPT Desktop users, full stop, today. The spec notes these are expected-support figures for the DevDay launch, so the matrix may widen. I would not build a business on a timeline that is not written down anywhere.
The portability bill
Here is the part that matters if you maintain MCP servers for a team. Every one of the 13 features is an openai/-namespaced _meta key or method: _meta["openai/ui"], _meta["openai/resource"], openai/resources/write. Host capabilities are advertised under experimental: { "openai/resource": {} } in the initialize result.
Two readings are possible and both are defensible. One: this is the MCP way, _meta exists precisely so hosts can extend without forking the protocol, and other hosts will simply ignore keys they do not know. Two: every feature you build on the namespace only renders in ChatGPT, so your server gradually becomes a ChatGPT plugin that happens to speak MCP elsewhere. There is also a stack of drafts underneath: MCP Apps itself is still a draft specification, so this is a namespaced extension on top of a moving base.
You can see both readings in the wild this week. Pi 1.0 added MCP by default after a year of arguing it did not need it, while Anthropic pushes skills as a lighter alternative. The protocol layer is where the vendors are now competing, and namespace-prefixed metadata is the weapon of choice.
What I'd pin down before adopting
Capability-detect instead of assuming. Your server can read hostCapabilities.experimental from the initialize result and only advertise the openai/ surface when the host actually implements it:
// after initialize, inspect the host's capabilities
const hasFileAccess = hostResult.capabilities?.experimental?.["openai/resource"];
if (!hasFileAccess) {
// register plain tools only, skip entrypoint metadata
}
Beyond that, three rules of thumb. Keep the openai/ surface a thin adapter layer over a portable core, so the file viewer is a shell around tool semantics any host can call. Pin the SDK version, 0.1.0 means the spec can shift under you, and version the extension surface in your own config the way you version anything else. And measure what the extra metadata does to your per-session token spend before rolling it out team-wide, the same exercise I ran when nine MCP servers cost 41k tokens before the first prompt.
If you maintain agent configs across tools, this release is one more surface to track, and one more reason to keep host-specific behavior quarantined in adapters rather than smeared through your rules files. It is the same discipline we apply when configs drift or when deciding what belongs in MCP at all. Our AgentConfig Studio kits apply that separation by default, with host adapters kept apart from the portable core.
The extensions themselves are good engineering. The ETag writes and the app-server path boundary are better designed than most of what passes for plugin systems. Just go in with eyes open: every openai/ key you add is a small bet on one host, and the house publishes the odds in a platform table that currently has a lot of "Not supported" cells.
Top comments (0)