On This Page8 sections
Key Takeaways
- The modern ChatGPT plugin architecture is different from the original 2023 plugin system. In 2026, plugins can combine reusable skills, MCP-backed integrations, and optional UI rather than relying primarily on the old
ai-plugin.jsonapproach. - Not every plugin needs a backend. A skills-only plugin can package repeatable instructions, templates, scripts, and reference material. Add an MCP server when the workflow needs live data, authentication, APIs, or external actions.
- MCP is the core integration layer for live capabilities. Production servers expose focused tools through a stable HTTPS endpoint, typically using Streamable HTTP.
- Custom UI is optional. Add it when users need to inspect, compare, edit, select, or confirm structured information—not simply because a plugin can have a UI.
- Authentication belongs on the server. Private user data and write actions should use the MCP authorization model, OAuth 2.1-compatible flows, PKCE, scoped permissions, and server-side authorization checks.
- Tool-selection testing is as important as API testing. A reliable plugin must call the right tool with the right arguments and avoid calling tools when the request does not require them.
What Is a ChatGPT Plugin in 2026?
The meaning of ChatGPT plugin has changed substantially since the first plugin ecosystem appeared.
Older tutorials commonly describe three pieces: an HTTP API, an OpenAPI specification, and a /.well-known/ai-plugin.json manifest. Developers following those guides today can easily end up implementing an architecture that no longer represents OpenAI's primary plugin model.
The current system is better understood as a package of capabilities. A plugin can contain:
- Skills for reusable instructions and workflows.
- MCP servers for live data and controlled actions.
- Optional UI resources for interactive experiences.
- Plugin metadata and assets for packaging and distribution.
OpenAI's current documentation describes plugins as a shared capability layer for ChatGPT and Codex. Apps remain integrations with external services, while plugins can package skills, apps, MCP capabilities, or combinations of them into reusable workflows.
That distinction is the most important thing to understand before writing code.
Choose the Right Plugin Architecture
Start with the smallest architecture that can complete the user's job.
| Architecture | Best for | Backend? | UI? |
|---|---|---|---|
| Skills only | Procedures, templates, repeatable instructions | No | No |
| MCP server only | APIs, databases, live lookups, actions | Yes | No |
| Skills + MCP | Multi-step workflows using live systems | Yes | Optional |
| MCP + UI | Interactive editors, comparisons, maps, complex state | Yes | Yes |
OpenAI explicitly supports these different plugin shapes rather than requiring every plugin to contain every layer.
A useful design rule is:
Use a skill when ChatGPT needs to know how to perform a workflow. Use MCP when ChatGPT needs to access or change something outside the conversation.
Step 1: Define a Specific User Job
Do not begin with a vague goal such as "build an analytics plugin."
Define an outcome instead:
- Find a customer and summarize recent support activity.
- Search company documentation for an implementation answer.
- Retrieve an order and report its shipping status.
- Create a project task from a natural-language request.
- Turn supplied engineering notes into standardized release notes.
For every capability, document:
- User intent — what problem is being solved.
- Required input — the minimum data needed.
- Read or write behavior — whether external state changes.
- Expected output — preferably structured fields.
- Failure states — invalid IDs, missing permissions, rate limits, and unavailable dependencies.
- Confirmation requirements — particularly for consequential actions.
This exercise prevents the most common architectural problem: building a collection of generic tools whose responsibilities overlap.
Step 2: Create a Skills-Only Plugin
A skill is the simplest plugin building block. Each skill has a SKILL.md file containing metadata and workflow instructions. Optional scripts, templates, references, and assets can live alongside it.
A minimal structure looks like this:
release-plugin/
├── plugin.json
└── skills/
└── release-notes/
└── SKILL.mdA portable plugin.json can begin with:
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "release-notes-helper",
"version": "1.0.0",
"description": "Turns technical change lists into concise release notes."
}OpenAI's current packaging documentation uses the root plugin.json as the portable plugin entry point and discovers packaged skills from the root skills/ directory.
Then create skills/release-notes/SKILL.md:
---
name: release-notes
description: Convert supplied product changes into concise release notes for end users.
---
Use this workflow when the user provides engineering changes, pull-request notes, or changelog items and asks for release notes.
1. Group related changes by user impact.
2. Remove unnecessary implementation detail.
3. Separate features, improvements, and fixes when supported by the input.
4. Never invent dates, version numbers, compatibility claims, or features.
5. Clearly identify breaking changes when present.The description is important because it helps determine when the skill should be considered. Detailed procedures belong in the instructions rather than being crammed into the description.
When skills alone are enough
Use a skills-only plugin for:
- Writing standards.
- Review procedures.
- Internal playbooks.
- Reusable analysis workflows.
- Templates.
- Packaged reference material.
- Repeatable transformations of user-provided data.
An MCP server is unnecessary when no live system needs to be accessed.
Step 3: Build an MCP Server for Live Capabilities
Add an MCP server when the plugin needs to:
- Search a live database.
- Call an existing SaaS API.
- Read private account information.
- Create or update records.
- Trigger business processes.
- Run controlled server-side logic.
OpenAI currently points developers toward the official TypeScript and Python MCP SDKs. Production MCP servers should be exposed through a stable HTTPS endpoint using an appropriate MCP transport such as Streamable HTTP.
A basic Node project can start with:
npm init -y
npm install @modelcontextprotocol/sdk zodWhen the plugin also needs MCP Apps UI helpers:
npm install @modelcontextprotocol/ext-appsOpenAI's current UI quickstart uses these MCP packages and exposes the server through an /mcp endpoint.
Step 4: Design Small, Specific Tools
Tool design affects reliability more than many developers expect.
For a project-management integration, good tool names include:
search_tasksget_taskcreate_taskcomplete_task
Weak alternatives include:
runexecutemanagedo_action
A tool should communicate:
- What object it operates on.
- Whether it reads or writes data.
- When it should be used.
- Which arguments are required.
- What it returns.
A simplified MCP tool might look like this:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
const server = new McpServer({
name: "project-tools",
version: "1.0.0"
});
server.tool(
"get_task",
"Return one existing task by stable task ID. This tool is read-only.",
{
taskId: z.string().min(1)
},
async ({ taskId }) => {
const task = await loadTask(taskId);
if (!task) {
return {
content: [{ type: "text", text: "Task not found." }]
};
}
return {
content: [{ type: "text", text: JSON.stringify(task) }]
};
}
);SDK APIs can evolve, so implementation syntax should always be checked against the installed MCP SDK version. The architectural principle is stable: each tool should expose one clear capability through a strict schema and predictable behavior.
Step 5: Return Structured Data
The model consumes tool results before presenting them to the user. Stable structured fields therefore make downstream reasoning more reliable.
Instead of returning only:
The checkout task is blocked and has high priority.return something like:
{
"id": "task_123",
"title": "Fix checkout",
"status": "blocked",
"priority": "high"
}Structured results improve:
- Follow-up tool calls.
- Validation.
- UI rendering.
- Logging.
- Automated testing.
- Compatibility when presentation changes.
MCP tools can define structured inputs and outputs, allowing the model to reason over predictable fields rather than scraping prose.
Step 6: Separate Read Tools From Write Tools
A read operation and a side-effecting action should never appear interchangeable.
For example:
find_invoice → read
create_invoice → write
cancel_invoice → consequential writeGood write tools should:
- Use names that reveal the action.
- Accept only necessary parameters.
- Validate authorization server-side.
- Return the resulting object or operation ID.
- Avoid hidden secondary actions.
- Be safe against duplicate execution where possible.
OpenAI's plugin guidance emphasizes predictable and auditable tool behavior and warns against hiding side effects.
Use idempotency for important writes
Agentic workflows can encounter retries and network failures. A create operation should therefore support an idempotency strategy when duplicate execution would cause damage.
Conceptually:
create_order(request, idempotency_key)Submitting the same key again should return the original operation rather than creating another order.
Step 7: Add OAuth for Private Data
Anonymous MCP tools work well for public information. User-specific data and write operations normally require authentication.
OpenAI's current authentication guidance follows the MCP authorization specification and describes OAuth 2.1-compatible authorization, PKCE, protected-resource metadata, scopes, discovery metadata, and token verification.
The flow conceptually looks like this:
ChatGPT
↓
MCP server discovers authentication requirements
↓
Authorization server
↓
User authenticates and grants scopes
↓
Access token
↓
ChatGPT calls MCP tool
↓
Server validates token and authorizationPrefer narrow scopes such as:
tasks.read
tasks.writeinstead of a broad permission such as:
account.full_accessNever trust identity supplied as a tool argument
A parameter such as userId is input, not authentication.
The backend should derive identity from the authenticated token or session and independently verify access to the requested resource.
Step 8: Add UI Only When Conversation Is Not Enough
A ChatGPT plugin does not require a custom interface.
UI becomes useful for workflows involving:
- Editable lists.
- Product comparisons.
- Maps.
- Schedules.
- Charts.
- Multi-item selection.
- Complex confirmations.
OpenAI's current architecture supports MCP Apps UI resources, but recommends keeping the underlying tools useful without the visual component.
A useful test is:
If the model cannot understand the result after the UI is removed, the MCP result probably contains too little structured information.
The tool contract should remain useful in headless environments.
Step 9: Package the Plugin
A portable plugin can use a structure like:
task-plugin/
├── plugin.json
├── mcp.json
├── skills/
│ └── task-triage/
│ ├── SKILL.md
│ └── references/
└── assets/
├── icon.png
└── logo.pngA remote MCP configuration can look like:
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
"mcpServers": {
"tasks": {
"type": "streamable-http",
"url": "https://plugin.example.com/mcp"
}
}
}OpenAI documents plugin.json, skills/, mcp.json, and optional assets as parts of the portable plugin structure. A .codex-plugin/plugin.json compatibility layout is also supported, but the root portable manifest is the preferred direction for new packages.
OpenAI-specific presentation and integration metadata can be placed under extensions.com.openai when needed.
Step 10: Test the MCP Server Independently
Do not debug protocol behavior and ChatGPT tool selection at the same time.
First verify the MCP server itself.
OpenAI's quickstart recommends the MCP Inspector for local testing.
npx @modelcontextprotocol/inspectorCheck that:
- Tool discovery succeeds.
- Schemas are correct.
- Valid tool calls work.
- Invalid arguments produce useful errors.
- Authentication challenges behave correctly.
- Returned structured content matches the declared contract.
Only after this layer is stable should ChatGPT behavior become the debugging target.
Step 11: Test Tool Selection in ChatGPT
A technically functioning MCP server can still produce a bad plugin if ChatGPT selects tools incorrectly.
Test positive prompts:
Find task task_123 and tell me why it is blocked.Create a high-priority task called Review launch checklist.Then test negative prompts:
Explain what task prioritization means.The last request should normally not trigger create_task merely because the word “task” appears.
Also test:
- Synonyms.
- Ambiguous requests.
- Missing arguments.
- Invalid IDs.
- Empty results.
- Permission failures.
- Rate limits.
- Repeated write requests.
- Requests unrelated to the plugin.
OpenAI's current quickstart specifically recommends testing invalid values and requests that should not invoke a tool.
Step 12: Connect the MCP Server to ChatGPT
OpenAI's current plugin quickstart uses the ChatGPT Plugins interface for custom MCP servers. The documented flow is broadly:
- Open the Plugins area.
- Select Add custom MCP server.
- Enter the server URL.
- Configure authentication.
- Review the risk warning.
- Create the connection as a plugin.
- Install it.
- Invoke it from a supported ChatGPT surface and test real prompts.
The official quickstart also describes a plugin directory shared by ChatGPT and Codex for supported public distribution.
Exact product labels and availability can vary by plan and rollout, so end-user installation documentation should be checked against the current UI before publishing it.
Step 13: Use @plugin-creator for Faster Packaging
OpenAI currently documents a built-in @plugin-creator workflow that can scaffold plugin packaging, connect registered MCP resources, and create local marketplace metadata for testing.
This can be useful when:
- The MCP server already works.
- Manifest boilerplate is slowing development.
- A personal or local test listing is needed.
- The plugin combines MCP capabilities with packaged skills.
Manual packaging remains useful when the repository needs explicit, portable configuration under source control.
Step 14: Prepare for Publication
A plugin that works privately is not automatically ready for public distribution.
OpenAI's current submission documentation describes requirements including identity or organization verification, appropriate platform permissions, review metadata, privacy information, test cases, and a publicly reachable production endpoint for remote MCP submissions.
Before submission, verify:
- HTTPS is enabled.
- No localhost or temporary development endpoints remain.
- Tool names and descriptions accurately represent behavior.
- OAuth works from a clean user session.
- Scopes follow least privilege.
- Write actions clearly expose side effects.
- The privacy policy matches actual data processing.
- UI resources have appropriate content security controls.
- Review prompts cover the main workflows.
- Failure states return useful responses.
Approval and publication are separate steps: OpenAI documents that an approved plugin must still be published before appearing in the public directory.
Security Best Practices
A plugin connects probabilistic model behavior with deterministic backend systems. Important security rules therefore belong in code, not prompts.
Validate every input
Treat MCP arguments as untrusted input.
Apply:
- Schema validation.
- Length limits.
- Enum restrictions.
- Identifier validation.
- Server-side authorization.
- Safe output handling.
Keep permissions out of prompt logic
An instruction such as “only administrators can use this action” is not an authorization mechanism.
The backend should evaluate:
authenticated identity
+
requested resource
+
required permission
+
authorization policybefore performing a protected operation.
Return only necessary data
If a workflow only needs an account tier and renewal date, avoid returning an entire customer record.
Data minimization reduces:
- Privacy exposure.
- Token usage.
- Latency.
- Model distraction.
- Logging risk.
Treat retrieved content as untrusted
Documents, webpages, CRM notes, and other external content can contain prompt-injection instructions.
Retrieved text should be treated as data, not as authority over backend policy.
Controls such as permissions, transaction limits, allowlists, and ownership checks belong in deterministic application code.
Common ChatGPT Plugin Mistakes
Following outdated ai-plugin.json tutorials
The old plugin model is still heavily represented in search results and archived tutorials. Current OpenAI documentation instead centers plugin development on skills, MCP servers, and modern plugin packaging.
Creating one giant tool
A tool called manage_account with dozens of optional parameters is difficult for both humans and models to reason about.
Prefer separate operations such as:
get_account
update_account_name
list_subscriptions
cancel_subscriptionMixing workflows into MCP business logic
The clean separation is:
Skill = how the workflow should be completed
MCP server = live data, permissions, and actionsOpenAI's skills documentation explicitly describes these components as complementary layers.
Returning prose for everything
Structured data is easier to chain, inspect, validate, and render.
Requesting overly broad OAuth scopes
A plugin that asks for more access than necessary creates unnecessary security and trust problems.
Letting the model enforce business rules
Rules such as refund limits, ownership checks, account permissions, and transaction constraints must be validated by the backend.
Building the UI first
A better development sequence is:
user job
→ tool contract
→ MCP implementation
→ protocol tests
→ ChatGPT invocation tests
→ optional UI
→ packaging
→ publicationHow to Write Better Tool Descriptions
Tool descriptions function as routing information for the model.
Weak:
Gets task information.Better:
Return the status, assignee, priority, and due date for one existing task identified by its stable task ID. Use this when the user asks about a specific task. This tool is read-only and does not modify the task.The stronger description defines:
- The object.
- The expected identifier.
- Returned fields.
- Invocation conditions.
- Side-effect behavior.
Descriptions for neighboring tools should be deliberately differentiated. If search_tasks and get_task appear semantically identical, inconsistent routing should be expected.
Reliability and Performance Tips
Use stable IDs
Prefer stable identifiers such as:
proj_abc123over mutable display names.
Separate search from fetch
For large datasets:
search_projects(query)
get_project(project_id)is usually more efficient than returning complete records for every search hit.
Support pagination
Do not assume result sets remain small.
{
"items": [],
"nextCursor": "cursor_123"
}Use machine-readable errors
Prefer:
{
"error": {
"code": "TASK_NOT_FOUND",
"retryable": false
}
}over an unexplained server error.
Make writes retry-safe
Read operations are generally safe to repeat. Write operations may require idempotency keys or other duplicate-prevention mechanisms.
Does a ChatGPT Plugin Need the OpenAI API?
No.
A plugin's MCP server can connect ChatGPT to:
- A proprietary API.
- A database.
- A search index.
- An internal application.
- A third-party service.
- A commerce backend.
- The OpenAI API.
The two concepts solve different problems.
A ChatGPT plugin exposes capabilities to ChatGPT. The OpenAI API allows software to invoke OpenAI models programmatically.
A plugin only needs to call the OpenAI API when its own backend has a separate reason to run a model.
Plugins vs Apps vs Skills vs MCP
| Layer | Primary responsibility |
|---|---|
| Plugin | Installable workflow and capability package |
| Skill | Reusable instructions, procedures, and resources |
| App / connection | Integration with an external service |
| MCP server | Tools, live data, authentication, and actions |
| UI resource | Optional interactive presentation |
OpenAI announced in July 2026 that app discovery had moved into the Plugin directory, with plugins becoming the primary discovery layer for workflow capabilities while apps continue to represent underlying integrations.
The most useful mental model is therefore:
Package the workflow as a plugin, put procedure in skills, expose live capabilities through MCP, and add UI only when visual interaction creates meaningful value.
Frequently Asked Questions
Can a ChatGPT plugin be created without coding?
Yes. A skills-only plugin can package instructions and resources without a live backend. An MCP-backed integration generally requires code or an existing MCP-compatible service.
Does every plugin require an MCP server?
No. Skills-only plugins are supported.
Does every MCP plugin need a custom UI?
No. UI is optional, and many search, lookup, and action workflows work better as headless MCP tools.
Can plugins access private user data?
Yes, when appropriate authentication and authorization are implemented. OpenAI's current MCP authentication guidance is based on OAuth-compatible authorization flows and scoped permissions.
Can ChatGPT plugins perform write actions?
Yes. MCP tools can expose controlled write operations. Side effects should be explicit, authorized server-side, and designed to prevent accidental duplicate execution where appropriate.
Is ai-plugin.json still the primary way to create a ChatGPT plugin?
No. Current OpenAI developer documentation centers modern plugin development on skills, MCP servers, and plugin.json-based packaging. Older tutorials should be treated as historical unless maintaining a legacy integration.
Can one plugin work in both ChatGPT and Codex?
OpenAI currently describes a universal plugin directory shared by ChatGPT and Codex. Portable skills and MCP configuration make cross-surface distribution possible, although surface-specific behavior should still be tested independently.
Production Checklist
Before releasing a plugin, confirm:
- Scope: every capability maps to a specific user job.
- Tool design: tools have distinct names and narrow responsibilities.
- Schemas: all arguments are validated.
- Authentication: private data uses appropriate authentication.
- Authorization: permissions are enforced server-side.
- Writes: side effects are explicit and retry-safe where necessary.
- Results: important data is returned in structured form.
- Errors: failures have actionable, machine-readable codes.
- Privacy: the plugin requests and returns only necessary data.
- Prompt injection: external content cannot override application security rules.
- Observability: tool calls have request IDs, errors, and latency measurements.
- Testing: positive, negative, ambiguous, and adversarial prompts have been evaluated.
- Deployment: the MCP endpoint is stable and HTTPS-accessible.
- Packaging:
plugin.json,mcp.json, skills, and assets are internally consistent. - Review: publication metadata, privacy disclosures, and test materials are complete.
Conclusion
Creating a ChatGPT plugin in 2026 is primarily an exercise in workflow design, MCP tool engineering, secure authorization, and reliable packaging rather than rebuilding the original plugin architecture.
The most effective development path is deliberately incremental: define one concrete user job, create a skill when instructions are enough, introduce MCP only when live capabilities are required, validate the server independently, test both correct and incorrect tool invocation, and add UI only when conversational output is insufficient.
The best first milestone is not a large multi-tool platform. It is one narrowly scoped skill or one read-only MCP tool that consistently activates for the correct request and stays inactive for unrelated requests. Once that behavior is reliable, authentication, write actions, UI, packaging, and public distribution can be added without turning the plugin into an untestable system.
Continue Reading
More articles connected to the same themes, protocols, and tools.
Referenced Tools
Browse entries that are adjacent to the topics covered in this article.








