How to Test an OpenAI Plugin Locally: A Complete Development Guide
To test an OpenAI plugin locally, run your development server, expose it via a public HTTPS tunnel using ngrok, update the host field in your .codex-plugin/plugin.json manifest to match the tunnel URL, and register that URL in the OpenAI developer console to invoke your endpoints through the Test tab.
The openai/plugins repository contains the reference implementations and scaffolding tools needed to build ChatGPT plugins, but testing them requires exposing your local development server to the internet via a secure HTTPS endpoint. This guide walks through the exact workflow defined in the official repository to verify your plugin functionality before deployment.
Start the Local Plugin Server
Every OpenAI plugin is fundamentally a web service that exposes HTTP endpoints described by a manifest file. To begin local testing, start the development server generated by the repository's scaffolding tools.
According to .agents/skills/plugin-creator/scripts/create_basic_plugin.py, the plugin creator skill generates a runnable server script (such as a Python Flask app or Node.js Express server) that serves your plugin's API endpoints:
# server.py – start a local plugin server
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route("/openai/v1/operations/list_items", methods=["POST"])
def list_items():
# Your business logic here
return jsonify({"items": ["Item 1", "Item 2"]})
if __name__ == "__main__":
app.run(port=5000) # http://localhost:5000
Run your server locally:
python server.py
This starts an HTTP server on localhost, which is not accessible to the OpenAI platform until you create a secure tunnel.
Expose Your Server via HTTPS Tunneling
The OpenAI platform only accepts HTTPS URLs and rejects plain HTTP endpoints, making a direct http://localhost connection impossible. You must tunnel your local server to the public internet using a service like ngrok.
As documented in plugins/zoom/skills/zoom-apps-sdk/references/full-guide.md, ngrok is the recommended tool for local plugin testing. It provides a secure HTTPS tunnel and a web interface for inspecting incoming requests.
Install ngrok and create a tunnel to your local port:
ngrok http 5000
Ngrok will return a public URL such as https://a1b2c3d4.ngrok.io. This URL is temporary and routes securely to your local machine, satisfying the platform's HTTPS requirement.
Update the Plugin Manifest
The manifest file located at plugins/<your-plugin>/.codex-plugin/plugin.json tells the OpenAI platform where to find your API and how to authenticate. You must update the host and api.url fields to point to your ngrok tunnel.
As outlined in the repository's README.md, the manifest structure follows this pattern:
{
"schema_version": "v1",
"name_for_human": "Example Plugin",
"name_for_model": "example_plugin",
"description_for_human": "Demo plugin used for local testing.",
"description_for_model": "Provides a list of example items.",
"auth": {
"type": "none"
},
"api": {
"type": "openapi",
"url": "https://a1b2c3d4.ngrok.io/openapi.yaml"
},
"host": "https://a1b2c3d4.ngrok.io"
}
Ensure all URL fields—including OAuth callback URLs and webhook endpoints if applicable—use the same ngrok base URL. The platform validates that these endpoints are reachable and secure before allowing testing.
Register the Plugin in the OpenAI Developer Console
Once your manifest references the public tunnel URL, register the plugin in the OpenAI developer console to begin testing.
- Navigate to Platform → Plugins → Create a plugin → Add a custom plugin.
- Paste your ngrok URL (e.g.,
https://a1b2c3d4.ngrok.io) into the Plugin URL field. - Click Fetch to validate the manifest and endpoints.
The console will retrieve your manifest from /.codex-plugin/plugin.json and verify that the specified endpoints respond correctly. This workflow mirrors the quick-start guide provided in plugins/zoom/skills/zoom-apps-sdk/references/full-guide.md.
Test and Debug Locally
After registration, the developer console displays a Test tab where you can invoke your plugin's actions directly. Requests from the ChatGPT UI travel through the ngrok tunnel to your local server, allowing you to see real-time logs and debug output.
For debugging assistance, refer to plugins/zoom/skills/zoom-apps-sdk/troubleshooting/debugging.md, which recommends using the ngrok request inspector to examine HTTP headers and payloads. This visibility is crucial when verifying that your local server correctly parses the platform's JSON payloads.
Example invocation from the test interface:
{
"model": "gpt-4o-mini",
"messages": [
{"role": "user", "content": "List the example items"}
],
"plugins": ["example_plugin"]
}
The request hits your local Flask endpoint via the tunnel, returns the JSON payload, and renders the result in the ChatGPT interface.
Handle OAuth Flows During Local Testing
If your plugin uses OAuth authentication, the redirect URL configured in your OAuth provider must also point to your ngrok tunnel. The authorization code is sent to this public URL and must be exchanged for an access token by your local server.
As detailed in plugins/zoom/skills/oauth/references/oauth-errors.md, mismatched redirect URLs are a common source of authentication failures during local development. Ensure your local server securely stores access tokens server-side and never exposes them in frontend storage.
Summary
- HTTPS is mandatory: The OpenAI platform rejects all HTTP URLs, requiring a secure tunnel like ngrok for local development.
- Update the manifest: Change the
hostandapi.urlfields inplugins/<your-plugin>/.codex-plugin/plugin.jsonto match your public tunnel URL. - Use the official scaffolding: The plugin creator skill at
.agents/skills/plugin-creator/scripts/create_basic_plugin.pygenerates the server code and manifest structure you will modify. - Debug via ngrok: Inspect requests using ngrok's web interface, as recommended in
plugins/zoom/skills/zoom-apps-sdk/troubleshooting/debugging.md. - Test in the console: The OpenAI developer console's Test tab is the canonical interface for invoking your plugin against your local server.
Frequently Asked Questions
Do I need HTTPS to test an OpenAI plugin locally?
Yes, the OpenAI platform strictly requires HTTPS endpoints and will reject any HTTP URLs, including localhost. You must use a tunneling service like ngrok to expose your local server via a public HTTPS URL before the platform can communicate with it.
Can I use alternatives to ngrok for local testing?
Yes, while ngrok is the tool referenced in plugins/zoom/skills/zoom-apps-sdk/references/full-guide.md, any service that creates a secure HTTPS tunnel to your local machine (such as Cloudflare Tunnel or localtunnel) will work, provided it offers a stable public URL and supports the HTTP methods your plugin requires.
Why does my manifest need to use the public tunnel URL?
The manifest file at plugins/<your-plugin>/.codex-plugin/plugin.json contains the host field and API definitions that tell the OpenAI platform where to send requests. If these fields point to localhost, the platform cannot reach your server. Updating them to the ngrok URL ensures the platform routes traffic through the tunnel to your development machine.
How do I debug requests when testing locally?
Use the ngrok web interface (typically at http://localhost:4040) to inspect the raw HTTP requests and responses between the OpenAI platform and your local server. As noted in plugins/zoom/skills/zoom-apps-sdk/troubleshooting/debugging.md, this request inspector is essential for verifying headers, authentication tokens, and payload formatting during development.
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 →