Repository navigation
Implement ChatGPT Plugin #42
Copy link
Copy link
Closed
Labels
help wantedExtra attention is neededExtra attention is needed
Description
Let ChatGPT control the user's keyboard and mouse
- add fastapi endpoint
- host in AWS labmda
.envto configure programmatically e.g. via terraform and/or Python wrapped aws cli- OpenAI manifest:
https://platform.openai.com/docs/plugins/getting-started
The minimal definition of the required ai-plugin.json file will look like the following:
{
"schema_version": "v1",
"name_for_human": "TODO Plugin",
"name_for_model": "todo",
"description_for_human": "Plugin for managing a TODO list. You can add, remove and view your TODOs.",
"description_for_model": "Plugin for managing a TODO list. You can add, remove and view your TODOs.",
"auth": {
"type": "none"
},
"api": {
"type": "openapi",
"url": "http://localhost:3333/openapi.yaml",
"is_user_authenticated": false
},
"logo_url": "http://localhost:3333/logo.png",
"contact_email": "support@example.com",
"legal_info_url": "http://www.example.com/legal"
}
The OpenAPI specification is the wrapper that sits on top of your API. A basic OpenAPI specification will look like the following:
openapi: 3.0.1
info:
title: TODO Plugin
description: A plugin that allows the user to create and manage a TODO list using ChatGPT.
version: 'v1'
servers:
- url: http://localhost:3333
paths:
/todos:
get:
operationId: getTodos
summary: Get the list of todos
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/getTodosResponse'
components:
schemas:
getTodosResponse:
type: object
properties:
todos:
type: array
items:
type: string
description: The list of todos.
The following Python code is an example of how you can set up a simple proxy of your public facing API.
import requests
import os
import yaml
from flask import Flask, jsonify, Response, request, send_from_directory
from flask_cors import CORS
app = Flask(__name__)
PORT = 3333
# Note: Setting CORS to allow chat.openapi.com is required for ChatGPT to access your plugin
CORS(app, origins=[f"http://localhost:{PORT}", "https://chat.openai.com"])
api_url = 'https://example.com'
@app.route('/.well-known/ai-plugin.json')
def serve_manifest():
return send_from_directory(os.path.dirname(__file__), 'ai-plugin.json')
@app.route('/openapi.yaml')
def serve_openapi_yaml():
with open(os.path.join(os.path.dirname(__file__), 'openapi.yaml'), 'r') as f:
yaml_data = f.read()
yaml_data = yaml.load(yaml_data, Loader=yaml.FullLoader)
return jsonify(yaml_data)
@app.route('/openapi.json')
def serve_openapi_json():
return send_from_directory(os.path.dirname(__file__), 'openapi.json')
@app.route('/<path:path>', methods=['GET', 'POST'])
def wrapper(path):
headers = {
'Content-Type': 'application/json',
}
url = f'{api_url}/{path}'
print(f'Forwarding call: {request.method} {path} -> {url}')
if request.method == 'GET':
response = requests.get(url, headers=headers, params=request.args)
elif request.method == 'POST':
print(request.headers)
response = requests.post(url, headers=headers, params=request.args, json=request.json)
else:
raise NotImplementedError(f'Method {request.method} not implemented in wrapper for {path=}')
return response.content
if __name__ == '__main__':
app.run(port=PORT)
Plugin API responses should return raw data instead of natural language responses unless it’s necessary. ChatGPT will provide its own natural language response using the returned data.
{ "todos": [ "get groceries", "walk the dog" ] }
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
help wantedExtra attention is neededExtra attention is needed
Activity
abrichr commentedon Jan 17, 2026
Closing as part of architecture transition. Legacy frozen at v0.46.0. See PR #960.