# How to Add MCP Servers to a Plugin in the OpenAI Plugins Monorepo

> Learn how to add MCP servers to your OpenAI plugin. This guide covers using @ai-sdk/mcp, setting up HTTP endpoints, registering URLs, and documenting tool schemas for seamless integration.

- Repository: [OpenAI/plugins](https://github.com/openai/plugins)
- Tags: how-to-guide
- Published: 2026-06-28

---

**To add MCP servers to a plugin, create a Node.js service using `@ai-sdk/mcp`, expose an HTTP endpoint at `/mcp`, register the URL in your [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) manifest, and document tool schemas in [`SKILL.md`](https://github.com/openai/plugins/blob/main/SKILL.md) files.**

The openai/plugins repository implements the Model Context Protocol (MCP) to provide AI agents with discoverable, structured tool APIs. When you add MCP servers to a plugin, you create a runtime bridge that exposes tool logic while keeping the plugin's core definition declarative and Markdown-based. This approach follows the architectural patterns established in the Vercel, Render, and Supabase reference implementations.

## Step-by-Step Implementation Guide

### Step 1: Write the MCP Server Implementation

Create a TypeScript service that registers tool schemas using `@ai-sdk/mcp` or the Vercel-specific `mcp-handler` wrapper. Place this in your plugin's source tree, typically at `plugins/<plugin-name>/mcp/server.ts`.

This file contains the only runtime component that implements tool logic; the rest of your plugin remains pure Markdown and JSON configuration.

```typescript
// plugins/example/mcp/server.ts
import { createMCPServer } from '@ai-sdk/mcp'

const server = await createMCPServer({
  name: 'list_items',
  inputSchema: {
    type: 'object',
    properties: { 
      limit: { type: 'integer', minimum: 1, maximum: 100 } 
    },
    required: [],
  },
  outputSchema: {
    type: 'array',
    items: { type: 'string' },
  },
  handler: async ({ limit = 10 }) => {
    return Array.from({ length: limit }, (_, i) => `Item ${i + 1}`)
  },
})

await server.listen({ port: 3000, path: '/mcp' })
console.log('MCP server listening on http://localhost:3000/mcp')

```

### Step 2: Export the MCP Endpoint

Add an HTTP route at `/mcp` by convention that the SDK will invoke. You can run this locally using `npm start` or deploy to cloud platforms like Vercel or Render.

The entry point is referenced from the plugin's [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) manifest file, which Codex uses to discover the endpoint automatically when loading the plugin.

### Step 3: Hook the Endpoint into the Plugin Manifest

Edit `plugins/<plugin-name>/.app.json` to point to your MCP server URL. This manifest tells the Codex runtime where to find the server's tool definitions.

```json
{
  "name": "example-plugin",
  "description": "Demo plugin with an MCP server",
  "mcp": "https://example-plugin-mcp.vercel.app/mcp"
}

```

### Step 4: Describe the Tools in SKILL.md

Document each tool's `name`, `inputSchema`, and `outputSchema` in your plugin's [`SKILL.md`](https://github.com/openai/plugins/blob/main/SKILL.md) files. Create an "MCP Tools" section in `plugins/<plugin-name>/skills/<skill-name>/SKILL.md` using standard Markdown tables.

```markdown

### MCP Tools

| Tool | Input | Output |
|------|-------|--------|
| `list_items` | `{ "limit": number }` | `string[]` |
| `search_documents` | `{ "query": string }` | `string[]` |

```

This provides human-readable reference while the MCP server supplies authoritative schemas at runtime.

### Step 5: Update the Plugin's Description

Amend `plugins/<plugin-name>/.codex-plugin/plugin.json` to indicate that your plugin ships with an MCP server. This makes the capability discoverable in the plugin catalogue.

### Step 6: Deploy the Server

Deploy using platform-specific CLIs (Vercel, Render, etc.) or run locally for development. For Vercel deployments, the SDK recommends using the `@vercel/mcp-handler` package for streamlined integration.

This guarantees a stable, OAuth-protected endpoint that agents can call without handling raw tokens directly.

### Step 7: Generate Static Tool Definitions (Optional)

Run `mcp-to-ai-sdk` after deployment to bake tool schemas into static JSON. Execute this from the plugin root using `npm run generate-tools`.

This step improves start-up latency by avoiding round-trips to the live server for schema discovery.

## Platform-Specific Implementation Patterns

### Vercel MCP Server Pattern

For Vercel-hosted plugins, use the `@vercel/mcp-handler` wrapper to streamline deployment. The implementation follows the pattern shown in [`plugins/vercel/skills/vercel-api/SKILL.md`](https://github.com/openai/plugins/blob/main/plugins/vercel/skills/vercel-api/SKILL.md):

```typescript
// plugins/example/mcp/vercel.ts
import handler from '@vercel/mcp-handler'

export default handler({
  tools: [
    {
      name: 'search_documents',
      inputSchema: { 
        type: 'object', 
        properties: { query: { type: 'string' } }, 
        required: ['query'] 
      },
      outputSchema: { 
        type: 'array', 
        items: { type: 'string' } 
      },
      handler: async ({ query }) => {
        return ['doc1', 'doc2']
      },
    },
  ],
})

```

Deploy with the Vercel CLI, then use the generated URL as your MCP endpoint in [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json).

## Architectural Considerations

### MCP-First vs CLI-Fallback Strategy

Most plugins follow an **MCP-first** strategy for read-only operations, falling back to the provider's CLI or REST API for write operations. This hybrid pattern appears in [`plugins/vercel/skills/vercel-api/SKILL.md`](https://github.com/openai/plugins/blob/main/plugins/vercel/skills/vercel-api/SKILL.md), where MCP handles project queries while the CLI handles deployments.

### Transport Protocols and Authentication

Modern implementations use **Streamable HTTP** transport, replacing older SSE transport for improved efficiency. This update is reflected in recent Vercel plugin implementations.

Authentication flows are handled internally by the MCP server. For example, the Supabase MCP server documented in [`plugins/supabase/README.md`](https://github.com/openai/plugins/blob/main/plugins/supabase/README.md) implements OAuth 2.1 flows, ensuring agents interact with protected resources without managing raw tokens.

## Summary

- **Create** the MCP server in `plugins/<name>/mcp/server.ts` using `@ai-sdk/mcp` or `@vercel/mcp-handler`
- **Register** the endpoint URL in `plugins/<name>/.app.json` under the `mcp` key
- **Document** tool schemas in `plugins/<name>/skills/<skill>/SKILL.md` with input/output tables
- **Deploy** to stable endpoints (Vercel, Render) to ensure reliable agent access
- **Authenticate** using OAuth flows handled internally by the MCP server implementation
- **Optimize** startup performance by running `mcp-to-ai-sdk` to generate static JSON schemas

## Frequently Asked Questions

### What file do I edit to register an MCP server endpoint in my plugin?

Edit `plugins/<plugin-name>/.app.json` and add the `"mcp"` key with your server URL. This manifest file tells the Codex runtime where to locate your tool definitions, following the pattern established in the Render plugin's [`plugins/render/skills/render-mcp/SKILL.md`](https://github.com/openai/plugins/blob/main/plugins/render/skills/render-mcp/SKILL.md).

### How do MCP servers handle authentication in the openai/plugins repository?

MCP servers handle OAuth internally. For example, the Supabase implementation uses OAuth 2.1 flows managed within the server itself, allowing AI agents to call protected APIs without handling raw authentication tokens. Document any required login flows in your [`SKILL.md`](https://github.com/openai/plugins/blob/main/SKILL.md) files.

### What is the difference between MCP and CLI tool implementations in these plugins?

MCP servers provide structured, discoverable APIs for read operations, while CLI tools handle complex writes and deployments. The Vercel plugin demonstrates this hybrid approach: MCP exposes project information queries, while the CLI handles actual deployments to their platform.

### Can I run an MCP server locally during development?

Yes. Run your server locally using `npm start` and reference the local URL (e.g., `http://localhost:3000/mcp`) in your [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) manifest. For production, deploy to Vercel, Render, or similar platforms and update the manifest with the production URL.