How to Integrate a Custom MCP Server with OpenAI Plugins: Complete Implementation Guide
Integrating a custom MCP server with OpenAI plugins requires exposing a Model Context Protocol endpoint that returns a JSON tool catalog, registering the server in your plugin's .app.json manifest, and consuming the tools via the @ai-sdk/mcp client, which automatically handles OAuth 2.1 authentication and Streamable HTTP transport.
OpenAI plugins define capabilities through skill manifests (*.md files) and optional .app.json configuration files that point to Model Context Protocol (MCP) servers. According to the openai/plugins repository, this architecture allows AI agents to discover and execute custom tools as native functions, with the MCP client managing connection lifecycle, token refresh, and graceful shutdown.
Understanding the MCP Architecture in OpenAI Plugins
When implementing integrating a custom MCP server with OpenAI plugins, you create a bridge between the AI agent and your external service. The architecture flows through four distinct layers:
AI Agent → AI SDK (generateText/streamText) → MCP client (creates connection) → Custom MCP server
↑ ↓
Tool catalog Tool handlers
In plugins/vercel/skills/vercel-api/SKILL.md (lines 30-34), the specification requires the MCP endpoint to support SSE or Streamable HTTP transport and return a JSON catalog of tools. The client handles OAuth token refresh and transport negotiation automatically, while the server only implements the MCP JSON RPC contract.
Step-by-Step Integration Process
Expose an MCP Endpoint with SSE or Streamable HTTP
Your custom server must listen on a URL that supports MCP transport protocols. According to the source code at plugins/vercel/skills/vercel-api/SKILL.md (lines 30-34), the endpoint must return a JSON catalog of tools and handle OAuth authentication automatically for agents.
The server implementation requires:
- OAuth 2.1 authentication support for secure agent connections
- Streamable HTTP or Server-Sent Events (SSE) transport capability
- A JSON RPC contract exposing tool definitions with
inputSchemavalidation
Register the MCP Server in .app.json
The .app.json file tells Codex which MCP server to connect to. As documented in plugins/vercel/skills/vercel-api/SKILL.md (line 11), the skill's metadata.pathPatterns can include files such as .mcp.json so that the agent discovers the server without explicit configuration.
You can also reference the Wix plugin configuration at plugins/wix/.codex-plugin/plugin.json for an example of advertising a built-in MCP server.
Fetch the Tool Catalog at Runtime Using @ai-sdk/mcp
Inside your skill implementation, create an MCP client and request the available tools. The example in plugins/vercel/skills/ai-sdk/SKILL.md (line 13) demonstrates using createMCPClient to establish the connection and client.tools() to retrieve structured tool definitions.
These definitions are passed directly to the AI SDK's generateText or streamText calls, allowing the LLM to see your custom functions as available tools.
Execute Tools with Automatic Validation and Approval
When the AI agent invokes a tool, the SDK automatically validates arguments against the tool's inputSchema. As noted in plugins/vercel/skills/ai-sdk/SKILL.md (line 35), the system can request human approval before execution if configured.
The MCP client manages the entire lifecycle: connection establishment, OAuth token refresh, and graceful shutdown.
Implementation Examples
Deploying a Custom MCP Server with Node.js and Express
First, install the MCP helper package:
# Install the MCP helper package (renamed from @vercel/mcp-adapter)
npm install mcp-handler
Then create your server implementation:
// server.ts – minimal MCP server using the mcp‑handler helper
import { createMCPHandler } from "mcp-handler";
const handler = createMCPHandler({
// Define a simple tool that returns the current time
getTime: {
description: "Get the current server time",
inputSchema: {}, // no arguments
outputSchema: { time: "string" },
handler: async () => ({ time: new Date().toISOString() }),
},
});
import express from "express";
const app = express();
app.use("/mcp", handler); // MCP endpoint at /mcp
app.listen(3000, () => console.log("MCP server listening on http://localhost:3000/mcp"));
This implementation exposes your tools at the /mcp endpoint. The deployment instructions are documented in plugins/vercel/skills/vercel-api/SKILL.md (lines 89-97), which specifies using the mcp-handler package to simplify JSON RPC implementation.
Connecting to the Custom MCP Server from Plugin Code
Use the AI SDK to consume your MCP server:
import { generateText } from "ai";
import { createMCPClient } from "@ai-sdk/mcp";
async function run() {
// Create a client that talks to our custom server
const mcpClient = await createMCPClient({
transport: {
type: "sse", // or "streamable-http"
url: "http://localhost:3000/mcp", // ← custom MCP endpoint
},
});
// Pull tool definitions from the server
const tools = await mcpClient.tools();
// Let the LLM use the new tool
const result = await generateText({
model: "openai/gpt-4o-mini",
tools,
prompt: "Use the available tools to tell me the current time.",
});
console.log(result);
await mcpClient.close();
}
run();
This snippet mirrors the official example in plugins/vercel/skills/ai-sdk/SKILL.md (line 13), demonstrating how the client fetches the tool catalog and makes it available to the LLM.
Implementing REST API Fallbacks for Missing Tools
When a tool is unavailable via MCP, fall back to direct API calls:
import { Vercel } from "@vercel/sdk";
const vercel = new Vercel({ bearerToken: process.env.VERCEL_TOKEN });
const { deployments } = await vercel.deployments.list({ limit: 5 });
console.log("Recent deployments:", deployments.map(d => d.url));
According to plugins/vercel/skills/vercel-api/SKILL.md (line 48), agents should prefer the MCP server for read operations but can fall back to CLI or direct REST calls for write operations or when the MCP server is unreachable.
Summary
- Integrating a custom MCP server with OpenAI plugins requires implementing the Model Context Protocol specification with OAuth 2.1 and Streamable HTTP transport.
- Register your server in
.app.jsonor usemetadata.pathPatternswith.mcp.jsonfiles for automatic discovery, as shown inplugins/vercel/skills/vercel-api/SKILL.md. - Use
createMCPClientfrom@ai-sdk/mcpto fetch tool catalogs and manage connections automatically. - The AI SDK validates tool arguments against
inputSchemaand supports human approval workflows before execution. - Implement REST API fallbacks for operations that require direct platform access or when MCP connectivity fails.
Frequently Asked Questions
What transport protocols does a custom MCP server support?
Custom MCP servers must support Streamable HTTP or Server-Sent Events (SSE) for real-time communication. The transport type is specified when creating the MCP client via the transport.type parameter, as implemented in plugins/vercel/skills/ai-sdk/SKILL.md.
How does authentication work between the plugin and MCP server?
The MCP client automatically handles OAuth 2.1 authentication and token refresh. According to the source code in plugins/vercel/skills/vercel-api/SKILL.md (lines 30-34), the endpoint must support OAuth for agent connections, but the plugin developer does not manually manage tokens—the @ai-sdk/mcp client manages the entire authentication flow.
Can I integrate an MCP server without using the AI SDK?
While the AI SDK (@ai-sdk/mcp) provides the most streamlined integration, the underlying protocol is standard JSON RPC over HTTP. However, the OpenAI plugins ecosystem specifically expects the client implementation shown in plugins/vercel/skills/ai-sdk/SKILL.md, which handles tool catalog parsing and execution validation that would otherwise require manual implementation.
When should I use MCP tools versus direct REST API calls?
Use MCP tools for read operations and standardized function calls that benefit from automatic schema validation and discovery, as noted in plugins/vercel/skills/vercel-api/SKILL.md (line 48). Use direct REST API calls or CLI fallbacks for write operations, complex authentication flows, or when the MCP server is temporarily unavailable.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →