← Blog

2023-03-25

A ChatGPT-Plugins Playground, Before the Tooling Existed

On March 23, 2023, OpenAI announced ChatGPT plugins: a manifest file, an OpenAPI spec, and a promise that the model could now reach out into the world. Two days later I created this repo. Not because I had a plugin to ship — because I had no way to watch one run.

Alt-GPT in action: selecting plugins, watching intent classification pick which one applies, and seeing the augmented completion come back — all client-side.

To actually try a plugin in early 2023 you needed a ChatGPT Plus subscription, an approved allowlist slot, and a tolerance for flying blind. There was no console. No way to see which plugin the model chose, what it sent, or what came back. No way to swap in a different key or a different vendor to compare. Every iteration was: edit, deploy, open ChatGPT, pray, guess.

That gap became alt-gpt-v0. It’s my most-starred repo — 158 stars — and it started from a mundane frustration: I couldn’t see what was happening.

What it was

Alt-GPT was a client-side playground. BYOK — bring your own key, no backend holding your credentials — with messages and settings persisted to localStorage. You could point it straight at the completion API, or select one or more plugins and watch the whole loop happen in the open.

The interesting part was that the model, in early 2023, wouldn’t do the orchestration for you. So I wrote a small piece I called the IntentSDK to do it by hand:

Alt-GPT v0.1 flow: user prompt → intent classification → fetch the plugin's OpenAPI spec → build and execute the call (direct or via proxy) → fold the result back into an augmented prompt → final completion.

  1. Classify the user’s intent, and decide which plugin(s) applied.
  2. Fetch the plugin’s OpenAPI definition and dynamically figure out how to call it.
  3. Execute the HTTP call. If the plugin’s server blocked cross-origin requests, funnel through a small local proxy instead of failing silently.
  4. Fold the response back in as augmented context, combine it with the original prompt, and send it to the model for the final completion — chainable, so one call could feed the next.

That last step wasn’t invented here. The whole shape is Retrieval-Augmented Generation (Lewis et al., 2020), which the README cites directly as inspiration:

RAG models where the parametric memory is a pre-trained seq2seq model and the non-parametric memory is a dense vector index of Wikipedia.

Alt-GPT swapped “dense vector index of Wikipedia” for “whatever a plugin’s OpenAPI spec exposes” — but the move is identical: retrieve external context, inject it, then generate.

Why this is a fossil worth keeping

None of that is exotic now. That’s the point.

In March 2023 there was no such thing as tool calling as an API primitive. You couldn’t ask a model to emit a structured function call and get a typed response — you did intent classification and manual orchestration yourself, in the client, because the model wasn’t going to. The scaffolding I was hand-rolling got standardized out from under it, in three fast steps:

  • June 13, 2023 — OpenAI shipped function calling in gpt-3.5-turbo-0613 and gpt-4-0613. The model now emitted the structured call itself.
  • November 6, 2023 — GPTs and “actions” absorbed the manifest-and-OpenAPI pattern at DevDay.
  • November 25, 2024 — Anthropic open-sourced the Model Context Protocol, pushing capability discovery down to a vendor-neutral protocol layer.

Plugins themselves didn’t make it. OpenAI blocked new plugin conversations after March 19, 2024 and shut existing ones off on April 9, 2024. The marketplace model died quietly; nobody wrote a eulogy.

What I got right, and what I got wrong

I bet on the packaging and lost. I implicitly assumed the “plugin” — a marketplace-listed, manifest-declared, human-installed capability — was the durable primitive. It wasn’t. It was a transitional container for an idea that turned out not to need a container at all.

The mechanism, though, held up almost unchanged: intent → capability discovery → structured call → context injection → completion. That five-step loop is exactly what tool calling does, and exactly what MCP does — just standardized and shoved one abstraction layer lower. I wasn’t predicting MCP. I was predicting that models would need a real way to reach outside themselves, and that whoever built on top of that reach needed to see it happening instead of trusting a closed UI.

Be honest about the limits of the thing itself: it never handled auth-based plugins (the README says as much — you had to smuggle an API key into the prompt), the CORS proxy was a workaround for a problem the ecosystem later solved properly, and hand-rolled intent classification was always going to be less reliable than a model fine-tuned to emit the call. It was scaffolding, and scaffolding is supposed to come down.

If you’re curious what a pre-tool-calling agent harness looked like, it’s worth a look — as a record of how much people were willing to build by hand before the labs standardized it for us. The demo still runs at alt-gpt.com.

Here’s the question I still don’t have a clean answer to: when the primitive you bet on gets absorbed into the platform, is the right move to keep the tool alive, or to let it die and treat the loop it proved as the actual deliverable? Where’s the line between a fossil and a maintenance burden?

References