Blog/2025-10-17/Custom GPTs

From Rest of What I Know
Revision as of 08:46, 17 October 2025 by Roshan (talk | contribs) (Created page with "thumb|Complete with unique logo I was a bit sceptical about OpenAI's [https://openai.com/index/introducing-gpts/ Custom GPTs] when they launched but that's because I did not know that they have 'Actions'. One of the things that Julie has wanted for a while is an LLM-assisted note taker. She wants to take short hand notes while in meetings and then have an LLM organize these, put a summary at the top, and note action items and...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Complete with unique logo

I was a bit sceptical about OpenAI's Custom GPTs when they launched but that's because I did not know that they have 'Actions'. One of the things that Julie has wanted for a while is an LLM-assisted note taker. She wants to take short hand notes while in meetings and then have an LLM organize these, put a summary at the top, and note action items and so on. Then she wants to be able to ask about someone and have the notes references and a synthesis given to her.

Requirements

  1. The thing has to work with ChatGPT - Julie is used to it, already uses it all the time, and would prefer to keep that
  2. The notes have to be human-readable - Julie intends to read the notes and look at them herself

Early Attempts

Notion MCP

This is a pretty reasonable use-case for an LLM, and at first I thought it must surely already have been built. In fact, Notion does have a remote MCP that you can use OAuth to authenticate into. This is a pretty good start, and you can then create a Custom GPT that reads from Notion pages and provides information and so on.

Two things that went wrong with this are:

  1. On read, it scans far too many pages to get to the relevant one
  2. It doesn't seem to want to write anything

The former is annoying because it makes everything rather slow, but the latter renders things useless. The Notion MCP page says that it should be able to read and write but when I follow the Notion MCP instructions to install it on ChatGPT in either Sync or Deep Research / Agent mode the LLM insists that it cannot write data.

Google Keep MCP

She'd been using Google Keep, for which you can build an MCP using an unofficial Python API that also requires you to use the legacy API token flow. That whole thing seemed a bit iffy, so I decided it was probably a bad fit. She wasn't particularly wed to Google Keep. She just wanted the idea of separate notes that she could look at with some collating notion. She's used Apple's Notes before as well.

Notion API

Julie'd gotten quite far with the Custom GPT thing by the time I asked her what she was doing. The GPT Builder LLM had suggested that she get a Notion Integration token, then write the OpenAPI spec that matches Notion's API for the Custom GPT Actions feature and use that as a custom GPT. This wasn't such a bad idea, but when I observed her at work and tried to help out we realized it wasn't going to work. The OpenAPI spec that ChatGPT 5 generated wasn't close to compliant for the GPT Builder (which is quite strict) and the GPT Builder could not format the JSON payload well enough for the API to handle it.

But this is a pretty common kind of error for LLMs: they do better when told a simple thing like "to create a note use `createNote(body: string)`" than if you tell them a complicated thing with multiple nested JSONs and this and that. As it so happened, the generated OpenAPI spec simply wouldn't provide the Custom GPT with a tool that it could use to create notes. Or rather, it would create notes but they'd all be empty. It couldn't update them either.

Final Solution

By the end, I thought perhaps it was the complexity of the API spec that made the whole thing hard to use. Besides, there are some problems that GPT-5 (even with Thinking enabled) just spazzes out on and others that Claude does that on. So I decided to try using Claude to write a constrained MCP that would only update this one Notion 'database' Julie by adding new notes, querying for notes, or updating notes. It did a marvelous job with a few edits, none of which I did with an IDE, and then I used my standard flow for hosting this. It requires an `X-API-Key` header that is well-supported by ChatGPT's Actions feature, and the MCP server also generates an OpenAPI spec for use here.

This worked wonderfully, and with a little work with the prompt Julie and I were able to finish her custom Julie Notes GPT.

Things We Learned

  1. The GPT Builder is pretty good at getting a software newbie up to quite a distance
  2. Cloudflare Tunnels don't work on nested domains (so you can't do a.b.julieyukang.com)
  3. Writing constrained tools that an LLM can call actually allows for more useful LLMs
  4. Writing constrained tools allows for far easier testing than trying to implement the API with Actions
  5. An MCP is a decent structure, but auth etc. is complicated
  6. A HTTP API is good because Claude Code can test itself and loop on feedback
  7. You can use the `x-openai-isconsequential` header to allow ChatGPT to enable the option for the user to select "Always Allow" on action calls

Overall, the end result is pretty useful already, and I keep thinking that I should build some kind of MCP so that I can expose our Apple Reminders (which is what Julie and I use currently to track our home/personal to-do lists).