CodeGym /Courses /ChatGPT Apps /User flow: how GPT suggests an App and invokes its functi...

User flow: how GPT suggests an App and invokes its functions

ChatGPT Apps
Level 1 , Lesson 2
Available

1. Introduction

Imagine you are building a regular web service. It’s straightforward there: you have a URL /search, the user clicks a button, you call the controller searchController. In the world of ChatGPT Apps, the user never sees any /search. They write human language:

"Pick a gift for my gamer brother up to $50"

And then:

  • the model decides: “Oh, this is about gifts, I have GiftGenius that can do this”;
  • GPT “presses the buttons” itself — calling your App’s tools;
  • sometimes it also offers the user: “Want me to open GiftGenius and show options?”

The key shift: the user expresses intent, and the model presses the buttons. If you don’t understand this flow, it’s easy to:

  • write tools with meaningless names (run_func, doStuff),
  • end up with an App that is never suggested by the model or is invoked inappropriately,
  • create a widget that “jumps out of nowhere” and breaks the conversation.

That’s why in this lecture we form the mental model: how GPT learns about your App at all and at what points in the conversation it “weaves it in.”

Insight: an app is a plugin to ChatGPT

Unlike apps on a phone or mini-apps in WeChat, apps in ChatGPT work differently.

ChatGPT itself decides when to launch your app and which of its functions to call. Apps in ChatGPT can actively (though with constraints) influence the chat’s logic. Their main goal and strength is to extend ChatGPT itself.

If ChatGPT can perfectly solve the user’s problem, it doesn’t need to call your app. If ChatGPT can’t solve the user’s problem at all, then users won’t ask about it there. The ideal case is when ChatGPT can solve the user’s request only partially. That means the requests exist, there are many of them, but the result is insufficient.

That’s when ChatGPT calls your app and together you make the user happy. The user gets happier — and you get richer.

2. Ways a ChatGPT App is launched from the user’s perspective

The user doesn’t have a button “call the MCP server and call_tool,” but they do have a text box and (sometimes) an app menu. From their point of view there are two basic launch modes: explicit and implicit.

Explicit launch (explicit)

This is the scenario when the user intentionally chooses your App.

Typical options:

  • they find your App in the ChatGPT Store and click “Open”;
  • they pick the App in the launcher (for example, via the + button in the Composer input);
  • they start the message with the app’s name: “GiftGenius, pick a gift…” — that’s called a named mention. If the App name is at the beginning of the prompt, ChatGPT automatically mixes your App into the answer’s context.

In explicit mode the model knows from the outset: the user came here to work with this App. Therefore:

  • GPT more frequently and more actively calls your tools;
  • your App’s UI widget can appear right in the first reply;
  • GPT is less likely to “ignore” the App and answer “on its own.”

A favorite example: the user opens GiftGenius directly because they want to “play around” with gift selection. They click the App in the list, and GPT shows a greeting like:

"Hi! I’m GiftGenius, I’ll help you pick a gift. Tell me who it’s for and what budget we’re working with."

And then it actively uses your tools to search.

Implicit launch (implicit / suggested)

A completely different scenario: the user isn’t thinking about an App at all. They just write in a regular chat:

"Pick a birthday gift for my mom; she loves gardening, budget up to $100"

GPT analyzes the request and sees that:

  • there’s an App GiftGenius in the ecosystem whose tools are described as “Use this when the user wants to get gift recommendations”;
  • the task and constraints (gift, budget, interests) match that App well.

The model may then “politely step in” with a suggestion:

"I can use the GiftGenius app to find concrete gift options and show them as cards. Open it?"

If the user agrees, GPT calls the necessary tool of the App and may render your widget.

Importantly, you never write if (prompt.includes("gift")) openApp(). The model makes the decision by itself, based on:

  • the text of the request and the conversation history;
  • your tool metadata (names, descriptions, parameter schemas);
  • the user’s connection state to the App (authenticated or not), whether they’re an enterprise user, etc.

You don’t influence the algorithm; you influence how your App and tools are “described” to the model.

Hybrid: when GPT clarifies first and then suggests the App

Sometimes the user writes something very general:

"I need to come up with something for a colleague — I have no idea what"

The model understands that GiftGenius can help, but the information is too vague. A common pattern:

  1. GPT asks 1–2 clarifying questions in text.
  2. After that, it offers to launch the App: “I have a gift selection tool. Want me to open it and show some options?”

That’s good UX: the user doesn’t feel like they were “forcibly moved into another app.”

3. Discovery: how GPT finds your App

Now let’s look at how this all works from the model’s point of view.

In the Apps SDK docs, this is called Discovery — all the ways the user and the model learn about your App at all. That includes organic chat requests, the app catalog, and special entry points such as the launcher.

How the model knows your App exists in the first place

When registering, ChatGPT launches your App, and it (via MCP) tells about itself: it lists available tools with their schemas — name, description, JSON schema of input parameters. You’ll provide app information during registration, and ChatGPT will fetch tool information itself via the MCP method list_tools.

The model doesn’t see your source code; it only has access to:

  • the tool’s name (name);
  • the description (description);
  • the input signature (inputSchema).

This becomes “the API for the model.” If you name a tool run_func with the description “Executes the function,” the model won’t know when to call it. If you name it suggest_gifts with the description “Use this when the user wants gift ideas based on recipient, occasion and budget,” everything becomes clear.

Named mention and in‑conversation discovery

The official Apps SDK spec highlights two key mechanisms:

  • Named mention — when the user starts a message with your App’s name. In that case, the App is almost guaranteed to be brought in and used in the reply.
  • In‑conversation discovery — when the user just writes a request, and the model decides whether to connect the App. It takes into account:
    • the conversation context (message history, results of previous tools, user preferences);
    • explicit brand mentions in the text;
    • your tool metadata — names, descriptions, parameter documentation;
    • link state — whether the user is connected to the App (authenticated, required permissions granted).

The developer influences this process indirectly: via high‑quality metadata and UX patterns, not via if/else in code.

Catalog and launcher

Beyond the conversational way, there’s also the Store inside ChatGPT and the launcher available from the composer. Through them, users can explicitly choose an App, like a regular app in a store.

For us this matters conceptually: when designing the GiftGenius flow, we must remember that:

  • some will come via the catalog and land directly “inside” the App;
  • some will never browse the catalog and will only see the App as a suggestion in chat.

All of this is about discovery of the App itself: the moments when the model decides whether to even “bring up” your app and suggest it to the user in the current conversation.

4. The anatomy of the interaction loop: from a phrase to a widget

Time to assemble all the layers from the previous lecture — from ChatGPT UI and widget to Apps SDK and the MCP server — into one clear logical loop.

High‑level diagram

From a process perspective, the loop looks like this:

sequenceDiagram
    participant U as User
    participant G as ChatGPT (model)
    participant A as App / MCP server

    U->>G: Text query
    G->>G: Request analysis + tool selection
    G->>A: Tool invocation (call_tool)
    A-->>G: Response (data / structuredContent)
    G->>U: Text response + (optional) App widget

In plain English:

  1. The user writes a message in ChatGPT.
  2. The model analyzes the request and current context and decides:
    • whether to answer by itself,
    • or call one or more tools.
  3. If a tool from your App is selected, ChatGPT forms a structured request (call_tool) and sends it to the MCP server.
  4. Your backend (or MCP server) performs the action: queries a database, external APIs, ACP, etc., and forms a result.
  5. The result is returned as structured data (and possibly JSON for a widget).
  6. The model uses these data to:
    • generate user‑friendly text,
    • and, if necessary, render the App’s widget right in the reply.

All the multi‑step planning — “when to call what,” “whether to ask a follow‑up,” “whether to make another call” — happens on the model side. Apps SDK and MCP simply provide a unified contract for tools.

Where we actually write code

In this loop there are three places where you actually write TypeScript/code:

  1. App and tool configuration — tool descriptions (name, description, schema) and App metadata (name, icon, categories). In your project, this is likely a file like openai/app-config.ts.
  2. MCP server / backend — handling call_tool: querying a DB, filtering products, calling other APIs, etc.
  3. Widget (UI) — a React component in a Next.js app that renders in the chat and reads tool results via window.openai or Apps SDK hooks.

Everything else is the model and the platform.

5. GiftGenius in action: two user flow scenarios

Let’s move to more concrete scenarios so you can “see” this flow.

Scenario 1: the user opens GiftGenius explicitly

Scenario:

  1. The user opens the App catalog in ChatGPT and finds GiftGenius.
  2. They click “Open.”
  3. ChatGPT starts the conversation already in the context of GiftGenius.

The conversation is roughly like this:

User:

Opens GiftGenius from the catalog.
And writes: "Hi! I want to pick a gift for a friend."

GPT:

"Great, let me help you pick a gift. Who is it for, what’s the budget, and what’s the occasion?"

At this step, GPT can immediately call a first tool, such as start_gift_session, to initialize a session in your backend (create a temporary cart, generate a sessionId, etc.).

Your code on the MCP server side might look like this (very schematic for now):

// Pseudo-example future-TS: GiftGenius tool definition
const suggestGiftsTool = {
  name: "suggest_gifts",
  description: "Use this when the user wants gift ideas by recipient, occasion and budget",
  inputSchema: {
    type: "object",
    properties: {
      recipient: { type: "string" },
      occasion: { type: "string" },
      budgetUsd: { type: "number" },
    },
    required: ["recipient", "occasion", "budgetUsd"],
  },
};
    

We’ll cover in detail how this is registered in MCP/Apps SDK in a separate module; for now, the key idea is: from this description the model understands that the tool fits “gift selection” requests.

After the user responds, GPT calls suggest_gifts, gets an array of options from you, and then:

  • writes a summary in text;
  • embeds the GiftGenius widget where the gift cards can be browsed and filtered.

Scenario 2: the user asks “pick a gift” in a regular chat

Now a different case: the user has no idea about GiftGenius.

They write in a regular chat:

"Need a gift for my brother, he loves board games, $50 max"

Inside ChatGPT the following roughly happens:

  1. The model analyzes the request and the list of available tools.
  2. It sees the tool suggest_gifts with a matching description.
  3. It understands that the GiftGenius App is designed for such tasks.
  4. It checks whether the user has already installed this App, was authenticated, and what permissions were granted.

Subsequent behavior may vary:

  • if the request is specific enough, GPT may silently call suggest_gifts and return a reply with a widget;
  • if something’s missing (e.g., no occasion or age), GPT can first ask a clarifying question in text and then suggest the App.

This flexibility is what distinguishes Apps from “rigid” UIs with forms: the model itself chooses when to use tools and when to talk.

6. Semantic routing: “LLM as dispatcher”

At the discovery level, the model decides whether to connect your App to the current request at all. But after the App has been “brought up” and its tools are known to the model in the current session, a second level kicks in — semantic routing among those tools: which specific tool should handle the next turn.

In a classic web backend the route is chosen by URL: /checkout — so you call the checkout controller. In ChatGPT Apps there’s no URL routing; instead there is semantic routing: the model compares the meaning of the request with your tool descriptions.

Simplified process:

  1. At session start, ChatGPT gets the list of tools: their names, descriptions, schemas.
  2. These data are embedded into the model’s system instructions.
  3. When the user writes a request, the model compares the request’s meaning to the tool descriptions: where “gift selection,” where “hotel search,” where “plot a chart.”
  4. If it finds a good match, it forms a structured call for the appropriate tool.

The main practical takeaway:

  • a tool’s description is your API for the model; read that again. Then again.
  • if you write “does stuff,” the model truly won’t know when to call it.

Docs and best practices for discovery emphasize: treat metadata like product copywriting. They determine in which conversations the model will recall your App.

7. Dialogue patterns around an App

Let’s look at typical UX patterns that occur when GPT interacts with an App within a single conversation. This matters so you don’t build an App “in a vacuum,” without understanding the GPT side’s role.

Most practical guides for the Apps SDK highlight several characteristic patterns:

“The Wizard”

GPT leads the user step by step, often leveraging the App.

Using GiftGenius as an example:

  1. GPT: “Tell me who the gift is for?”
  2. User: “My brother, 25, loves board games.”
  3. GPT: “What’s the budget?”
  4. User: “Up to $50.”
  5. GPT calls suggest_gifts, shows results in the widget, and writes: “I’ve picked a few options — take a look in the list below.”

In this pattern, the App and its widget act as the visual layer over a multi‑turn conversation. The user mostly writes text, and the widget helps visualize the choices.

“The Adaptive Widget”

Text remains the primary channel, and the App plugs in surgically for special tasks: plot a chart, show a table, render product cards.

Example:

  • User: “Compare three gift options: a board game, a book, and an experience gift.”
  • GPT first explains the pros and cons in text.
  • Then it calls a tool that returns a structured product list and renders a small table or set of cards.

Here the App is a visual add‑on, not the “default operating mode.”

“Invisible Agent”

The App might not show any UI at all. It works “under the hood” as a data source:

  • you implement an MCP tool that searches gifts in your DB;
  • GPT calls it, gets a list, and then summarizes the results in text with no widget.

This is similar to a classic “plugin with no UI”: the user only sees that GPT knows current prices and inventory.

This pattern is useful for a tool‑first App where UI isn’t critical.

8. How the flow influences App design

Understanding the flow matters not just philosophically but for very practical decisions: which tools to create, how to describe them, when to show a widget, and when it’s better to answer in text.

The “chat‑first” principle

The ecosystem’s core idea: chat is the primary interaction channel, and UI components are auxiliary.

This means:

  • don’t try to cram “an entire website” into one widget;
  • widgets should help where chat is inconvenient: choosing from a list, filtering, comparing, complex forms.

For GiftGenius this means:

  • select a list of gifts and let the user click through cards;
  • visualize filters (price, category, availability);
  • help place an order (checkout) in a few clear steps.

But writing a long essay in the widget on “how to choose a gift for an introverted girl” is not a great idea — that’s a job for chat.

When to launch the App and when not to

Another consequence: don’t turn the App into a “conversation hijacker.”

Bad pattern:

  • the user is having a serious discussion;
  • the App launches and opens a large fullscreen widget without warning;
  • the user gets lost: “where did my chat go?”

Better:

  • discuss everything in text first, ask a couple of clarifications;
  • then gently offer to open the App if it truly improves the UX (comparison, configuration, checkout).

Impact on the tool set

Since the model chooses a tool by description, each tool should:

  • solve one clear task;
  • be well described in the “Use this when…” style;
  • have parameters that naturally follow from the questions GPT will ask the user.

For GiftGenius, instead of one giant do_everything, it’s more logical to have:

  • suggest_gifts — select a list of options;
  • get_gift_details — details for a single ID;
  • create_order — place an order.

We’ll work on tool design in Module 4, but the general idea already matters: the conversation flow determines which tools are needed at all.

9. Mini‑example: how tool descriptions influence the flow (TypeScript sketch)

A small fragment of an imaginary openai/app-config.ts to connect theory with code. Don’t treat this as exact SDK syntax (we’ll cover it in the next module) — the important thing now is the idea of names and descriptions.

// Hypothetical fragment of the GiftGenius config (future code)
const tools = [
  {
    name: "suggest_gifts",
    description: "Use this when the user wants gift ideas based on recipient, occasion, and budget.",
    inputSchema: {/* ... */},
  },
  {
    name: "get_gift_details",
    description: "Use this when the user asks for more information about a specific gift from a previous list.",
    inputSchema: {/* ... */},
  },
];

If you replace suggest_gifts with run_func and the description with “Main function,” GPT will:

  • understand more poorly which requests this tool is for;
  • suggest your App less often in in‑conversation discovery;
  • struggle more to connect user follow‑ups with the already shown gift list.

Conversely, good names and descriptions increase the chance that your App pops up at the right moment.

10. Common mistakes when designing the user flow

Mistake #1: Expecting full control — “I’ll decide myself when to launch the App.”
Sometimes developers think in the paradigm “I’ll catch all gift requests and plug in my App.” In the world of ChatGPT Apps, it doesn’t work like that: the model makes the decisions. It considers tool descriptions, conversation context, permission state, and how satisfied the user is with calling your App specifically.

Mistake #2: Meaningless tool names and descriptions.
Tools named run, main, tool1 with descriptions like “Calls the main function” create the perfect storm: the model doesn’t know when to call them, in‑conversation discovery barely works, and your App becomes “invisible.” A good “Use this when the user wants…” description and a clear name are far more important than it may seem at first glance.

Mistake #3: Trying to cram “everything” into one App.
If your App simultaneously “picks gifts, books hotels, calculates taxes, and shows cat pics,” the model won’t reliably route requests. Official recommendations and practical guides emphasize the “one clear job per tool/App” principle: several specialized apps are better than one mega‑monolith.

Mistake #4: Aggressive auto‑launch of a heavy UI.
A developer is proud of their beautiful fullscreen widget and wants to show it “at every opportunity.” As a result, the user feels the chat “breaks” and turns into a strange web app. It’s much better when GPT first talks in text, asks clarifying questions, and only then offers to open the App, explaining why it helps.

Mistake #5: Ignoring GPT’s role as the UX layer.
You can design an App like a typical SPA: do everything in the widget, and ChatGPT should “keep quiet and not interfere.” That won’t work. ChatGPT may not display your widget, or may display a new widget for a new tool call. If you want a successful product, adapt to the platform — don’t expect it to adapt to you.

1
Task
ChatGPT Apps, level 1, lesson 2
Locked
Hello JSON with Metadata
Hello JSON with Metadata
1
Task
ChatGPT Apps, level 1, lesson 2
Locked
Hello Name with Normalization
Hello Name with Normalization
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION