MCP integrations

Purpose and Scope

Model Context Protocol, or MCP, is an integration pattern for giving a model access to tools and knowledge that live outside the prompt. In OpenAI platform documentation, remote MCP servers and OpenAI-maintained connectors are presented as tool surfaces: the model can decide when to call them, and the developer can choose whether calls run automatically or require approval. In this SDK page, treat MCP as part of the broader tool-calling model rather than as a standalone transport client. The OpenAI TypeScript and JavaScript SDK sends typed API requests, exposes generated tool-related request types, and provides helper runners for local function tools in Chat Completions workflows.

Sources: src/resources/chat/completions/index.ts, src/resources/chat/index.ts, src/lib/AbstractChatCompletionRunner.ts

This distinction matters when you are choosing where to implement an integration. A remote MCP server is an internet-reachable server that implements the MCP protocol and exposes external capabilities or data. A connector is an OpenAI-maintained MCP wrapper for a popular service. A local function tool, by contrast, is code you run inside your own Node, Bun, Deno, or edge process. The SDK evidence for this page is concentrated in Chat Completions tool types and helper runners, so the source-backed implementation details below focus on how tool-shaped workflows are represented and executed in this package.

Sources: src/lib/ChatCompletionRunner.ts, src/lib/ChatCompletionStreamingRunner.ts

Relevant Source Files

  • src/resources/chat/completions/index.ts - Re-exports the generated Chat Completions resource, request parameter types, response types, tool types, tool choice types, and message-list resource.
  • src/resources/chat/index.ts - Re-exports the Chat namespace and the same Chat Completions tool-related types from the higher-level chat entrypoint.
  • src/lib/AbstractChatCompletionRunner.ts - Implements shared runner state for chat tool workflows, including message accumulation, tool-call event emission, tool-call ID normalization, runner options, and the post-completion callback hook.
  • src/lib/ChatCompletionRunner.ts - Provides the non-streaming ChatCompletionRunner.runTools helper and its parameter type for runnable local tools or auto-parseable tools.
  • src/lib/ChatCompletionStream.ts - Defines streaming event types for content, chunks, refusals, logprobs, and function tool-call argument deltas and completion events.
  • src/lib/ChatCompletionStreamingRunner.ts - Provides the streaming ChatCompletionStreamingRunner.runTools helper and a fromReadableStream constructor for stream reconstruction.

Conceptual Model

The first design choice is whether the external capability belongs behind a remote MCP server, a hosted connector, or local application code. Use remote MCP when another service should expose tools through a protocol boundary and the model should call those tools through the API. Use connectors when an OpenAI-maintained integration already provides the service wrapper you need. Use local function tools when your JavaScript runtime should own execution, validation, approvals, secrets, and network boundaries. The SDK does not require these choices to look identical in code; it provides typed request surfaces and helper classes for the tool workflow you choose.

Sources: src/resources/chat/completions/index.ts, src/lib/ChatCompletionRunner.ts

In Chat Completions, tool integration appears through generated request and response types. The chat completions index exports ChatCompletionTool, ChatCompletionToolChoiceOption, ChatCompletionAllowedToolChoice, ChatCompletionAllowedTools, ChatCompletionFunctionTool, ChatCompletionMessageToolCall, ChatCompletionMessageFunctionToolCall, and the streaming and non-streaming create parameter types. Those names are important because they define the SDK-facing contract for message-based tool workflows: the request describes what tools may be called, the response may contain tool calls, and the application is responsible for feeding tool results back as messages when it owns execution.

Sources: src/resources/chat/completions/index.ts, src/resources/chat/index.ts

SDK Surface Mapping

The top-level chat namespace keeps the generated types reachable from the public SDK surface. src/resources/chat/index.ts re-exports Chat, Completions, the generated completion object types, message parameter types, tool choice types, and create parameter types from ./completions/index. This means application code can work from client.chat.completions while TypeScript users can still name the generated tool and message contracts from the chat resource family. For MCP-style workflows, that is the pattern to remember: the integration is modeled in the request body and response items, not by constructing a separate long-lived MCP connection object from these chat helper files.

Sources: src/resources/chat/index.ts, src/resources/chat/completions/index.ts

The runner helpers are specifically for local function-tool execution in Chat Completions. ChatCompletionRunner.runTools(client, params, options?) accepts non-streaming chat create parameters with tools replaced by RunnableTools or auto-parseable tools. ChatCompletionStreamingRunner.runTools(client, params, options?) does the same for streaming parameters. Both helpers add an X-Stainless-Helper-Method: runTools header and then invoke the shared _runTools machinery. That source-backed behavior is useful when you want the SDK to orchestrate repeated chat requests around locally executed functions, but it is not the same thing as hosting a remote MCP server.

Sources: src/lib/ChatCompletionRunner.ts, src/lib/ChatCompletionStreamingRunner.ts

Execution Flow for Tool Workflows

The shared runner keeps a mutable messages array and records parsed chat completions as they arrive. When a completion is added, the runner normalizes missing tool-call IDs, stores the completion, emits a chatCompletion event, and adds the assistant message to conversation state. The ID normalization is pragmatic: some OpenAI-compatible providers may omit or return an empty tool-call ID, so the runner generates a call_ identifier before storing or emitting the completion. This ensures an assistant tool call and its later result message can reference the same value.

Sources: src/lib/AbstractChatCompletionRunner.ts

After messages enter the runner, the shared implementation emits semantic events. Assistant messages with function tool calls produce functionToolCall events, and tool result messages with content produce functionToolCallResult events. RunnerOptions adds two control points: maxChatCompletions, which defaults to ten requests before canceling, and afterCompletion, an awaited callback that runs after each completion and any tool calls from that completion. The callback receives a runner context with messages and abort(), so application code can add context, stop the loop, or enforce approval gates between requests.

Sources: src/lib/AbstractChatCompletionRunner.ts

Streaming and Event Handling

Streaming tool workflows expose more granular events than the non-streaming runner. ChatCompletionStream is an async iterable over ChatCompletionChunk objects and defines events for raw chunks, content deltas, completed content, refusal deltas, completed refusals, logprob deltas, and logprob completion. For function tools, it exposes tool_calls.function.arguments.delta and tool_calls.function.arguments.done, each carrying the function name, tool index, accumulated arguments, parsed arguments, and argument delta where applicable. This is the right helper surface when you need to update a UI, inspect arguments incrementally, or delay execution until arguments are complete.

Sources: src/lib/ChatCompletionStream.ts, src/lib/ChatCompletionStreamingRunner.ts

The streaming runner also supports fromReadableStream(stream), which constructs a runner around an existing readable stream and starts consuming it through the inherited stream parser. That capability is separate from MCP itself, but it fits the same integration problem: once tools are involved, applications often need observable intermediate state. If a workflow combines remote MCP tools through the API with local UI or audit handling, use the stream events to separate display, approval, logging, and tool-result submission concerns instead of treating the response as a single final string.

Sources: src/lib/ChatCompletionStreamingRunner.ts, src/lib/ChatCompletionStream.ts

Compact Reference

SurfaceSource-backed contractUse it when
ChatCompletionToolGenerated chat tool type exported from chat completionsYou need to type a Chat Completions tool entry
ChatCompletionToolChoiceOptionGenerated tool-choice option typeYou need to control whether or which tool may be called
ChatCompletionAllowedToolsGenerated allowed-tools typeYou need to constrain tool availability
ChatCompletionCreateParamsNonStreamingNon-streaming create parametersYou are using ChatCompletionRunner.runTools
ChatCompletionCreateParamsStreamingStreaming create parametersYou are using ChatCompletionStreamingRunner.runTools
ChatCompletionRunner.runTools(client, params, options?)Runs local function tools with repeated non-streaming chat completionsYour runtime should execute tools and maintain chat state
ChatCompletionStreamingRunner.runTools(client, params, options?)Runs local function tools while exposing streamed chunks and tool-argument eventsYou need incremental UI or observability
RunnerOptions.afterCompletionAwaited callback after a completion and its tool calls finishYou need approval, mutation, or stop logic between turns

Practical Guidance

For new MCP work, start by deciding where the server or tool executes. If the tool is a remote MCP server or connector described by the OpenAI platform API, model it through the appropriate API request tool configuration and keep secrets, approval policy, and service access explicit. If the tool is local JavaScript code, use the Chat Completions runner helpers when message-based chat compatibility is required. For modern model workflows, also review the Responses API documentation and SDK surfaces, because official OpenAI docs position Responses as the primary API for model interaction and MCP built-in tools.

Sources: src/resources/chat/completions/index.ts, src/lib/ChatCompletionRunner.ts, src/lib/ChatCompletionStreamingRunner.ts

Related pages: responses-api, tools-approvals, connections, openapi-actions, streaming-events, chat-completions