---
title: "AI Agents Can Build Apps. Why Can’t They Use Them?"
canonical: "https://cogint.ai/ai-agents-can-build-apps-why-cant-they-use-them/"
description: "A firsthand PromptFax case study comparing seven ways an AI agent can interact with an application: embedding an LLM, computer use, browser control, an MCP server, MCP Apps, WebMCP, and direct API exposure through a custom GPT. The comparison finds no single universal discovery-and-execution layer; each approach trades off reach, setup, UI, host support, and developer effort."
author: "Chad Hart"
published: "2026-07-16T12:34:45.000-04:00"
modified: "2026-07-16T12:34:45.000-04:00"
site_tags:
  - "voice-ai"
machine_topics:
  - "AI Agents"
  - "MCP"
is_based_on: []
content_fidelity: "faithful_html_conversion"
annotations_not_part_of_article: true
word_count: 5466
approx_tokens: 7270
content_hash: "5826b5f86f1bf75d09f45d23f0d46c7305e2652d107a2b138e5929d41fe4a3cf"
markdown_url: "https://cogint.ai/ai-agents-can-build-apps-why-cant-they-use-them/index.md"
---

# Machine-oriented context

This section is generated metadata and is not part of the original article.

## Summary

A firsthand PromptFax case study comparing seven ways an AI agent can interact with an application: embedding an LLM, computer use, browser control, an MCP server, MCP Apps, WebMCP, and direct API exposure through a custom GPT. The comparison finds no single universal discovery-and-execution layer; each approach trades off reach, setup, UI, host support, and developer effort.

## Key findings

- Agent application access is fragmented across visual automation, browser APIs, tool protocols, embedded models, and platform-specific API integrations.
- Computer use has broad theoretical reach but is expensive and fragile because it operates through pixels and simulated input.
- MCP provides explicit tools and good developer ergonomics, while client discovery and installation remain separate concerns.
- MCP Apps adds interactive UI to MCP but depends on host support and host-specific integration work.
- WebMCP lets a page expose tools in-browser but was experimental and browser-dependent at the evaluation date.
- A custom GPT can expose a direct OpenAPI action effectively inside ChatGPT, but it is a platform-specific distribution path.

## Normalized comparison

| Approach | Interaction mechanism | Discovery | Main constraint |
| --- | --- | --- | --- |
| App-embedded LLM | Model runs inside the application | Application-specific | Strong product coupling; does not let outside agents operate the app |
| Computer Use | Pixels plus simulated mouse and keyboard input | Visual navigation | High latency and cost; sensitive to UI state |
| AI browser control | Browser or DOM automation | Agent and browser dependent | Sites cannot reliably assume or detect a common control layer |
| MCP Server | Typed tools served outside the website | Client configuration or registries | Requires a separate service and client connection |
| MCP Apps | MCP tools with an interactive embedded UI | MCP host installation | Host support and UI integration vary |
| WebMCP | Page-defined browser tools | Browser exposes tools for the current origin | Experimental and browser-dependent at evaluation time |
| Direct API through a custom GPT | OpenAPI-described actions | Explicit GPT configuration | Platform-specific distribution, authentication, and review |

## Provenance and sources

- Original cogint.ai article based on the author’s PromptFax implementations and tests.
- Tested or observed at: 2026-07-16 (publication-time comparison; individual implementation dates are not separately asserted)
- [Model Context Protocol specification](https://modelcontextprotocol.io/specification) — Model Context Protocol; official specification
- [MCP Apps Extension](https://blog.modelcontextprotocol.io/posts/2025-11-21-mcp-apps/) — Model Context Protocol; official announcement
- [SEP-1865: MCP Apps interactive user interfaces](https://modelcontextprotocol.io/seps/1865-mcp-apps-interactive-user-interfaces-for-mcp) — Model Context Protocol; official proposal
- [WebMCP proposal](https://github.com/webmachinelearning/webmcp) — W3C Web Machine Learning Community Group; official proposal repository
- [WebMCP early preview for Chrome](https://developer.chrome.com/blog/ai-webmcp-origin-trial) — Chrome for Developers; browser implementation documentation
- [OpenAPI specification](https://www.openapis.org/) — OpenAPI Initiative; official specification

## Limitations

- The comparison is a point-in-time practical evaluation, not a benchmark with uniform quantitative measurements.
- Browser, ChatGPT, MCP host, and experimental WebMCP behavior can change after the evaluation date.
- Normalized terminology in this annotation is editorial metadata and is not quoted from the published article.

# Published article

Faithful Markdown conversion of the human-readable article follows.

A few weeks ago I rage-coded a fax app ([promptfax.app](https://promptfax.app/?ref=cogint.ai)) after I was forced to send a fax again for the first time in a decade. I did not want to deal with sending a one-off fax, so like I often do with stasks I don’t want to deal with — I asked chatGPT and Claude to do it for me. Sadly, neither of them could send my fax on their own. The advice they gave me for how to do it was far less than ideal.

Agents can code complex apps in minutes, yet they can’t send a simple fax? How could this be? This set me off down a rabbit hole exploring how AI agents should implement a simple use case like this. There are so many ways to let an LLM interact with your app and do stuff—MCP, connectors, AI browsers, AI browser extensions, computer use, WebMCP… What is a web app supposed to do to help here? Are all of these needed? Which is best?

To answer these questions, I ended up making a simple web app aimed at humans. I then started looking into every option reasonably available to let an agent interact with my app. The landscape of options was way larger than I had previously thought about. There are big choices in how much control you want some external LLM agent to have vs. your own app. Some approaches are standardized, or on their way to be standardized. Others are only applicable to a single LLM vendor (i.e., OpenAI). The matrix below gives a starting summary.

![Two-axis matrix positioning Computer Use, Browser Control, MCP Server, MCP App, WebMCP, Custom GPT, and an in-app LLM by LLM-led versus app-led interaction and availability across products versus a single AI product.](https://cogint.ai/content/images/2026/07/gdoc-16TU-1pEqXCVAcK_O6Nn0fxcwP58NimVSHgHp_jIYBl8-7.png "Click to enlarge")

*I explored 7 different ways to integrate AI Agents with my app.*

I tested and/or implemented all of these. My learnings are outlined below. Given the limited scope of faxing, my focus was on general AI interaction with web apps. These mechanisms and interactions are not at all specific to my app, so I hope you find it helpful for your app.

## Contents

-   [Agent to App interaction mechanisms](#agent-to-app-interaction-mechanisms)
    -   [Add an LLM to the app](#add-an-llm-to-the-app)
    -   [Computer Use](#computer-use)
    -   [AI Browser Control](#ai-browser-control)
    -   [MCP Server](#mcp-server)
    -   [MCP Apps](#mcp-apps)
    -   [WebMCP](#webmcp)
    -   [Direct API Exposure → GPTs](#direct-api-exposure-%E2%86%92-gpts)
-   [Conclusions](#conclusions)

## Agent to App interaction mechanisms

### Add an LLM to the app

Shoving an LLM chatbox onto the page is a very common approach and is where I started. Most of the time embedded website chat agents are hooked into some Retrieval-Augmented Generation (RAG) system to answer questions. Answering questions is easy. Having them execute actions is more complex. If your app is relatively simple and built with the right abstractions, it shouldn’t be too hard to map your internal API functions to LLM tools. Then the LLM can invoke those tools as needed.

My first thought was, why not just expose a chatbox and skip the tedious work of building a GUI altogether? I really like how apps like [lovable.dev](https://lovable.dev/?ref=cogint.ai) just give you a prompt and let you build things. It turns out that a text prompt is a horrible user interface for doing most simple things. There is a reason personal computers stopped booting to a prompt decades ago. In my case, the simple steps of adding a document, a phone number, and providing a quote via chat were way more tedious than just making a couple of clicks.

![Animated PromptFax interface showing a user asking whether chat is better than the existing controls, followed by the assistant recommending the buttons for uploading, entering a fax number, paying, and sending.](https://cogint.ai/content/images/2026/07/promptfax-chat-loop.gif "Click to enlarge")

*The in-app chat could drive the same fax workflow, but typing through it was slower than using the controls.*

If your UX is good, the user shouldn’t need to ask questions or type what they need to do. I kept the in-app LLM for anyone who wants to use it (one so far), but demoted its prominence.

<table style="width:100%;min-width:640px;border-collapse:collapse;table-layout:fixed;white-space:normal;overflow-wrap:anywhere"><tbody><tr><td colspan="2" style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f2f3f5;font-weight:700;font-size:1.05em"><p><strong>In-app LLM — an app-owned chat and tool interface</strong></p></td></tr><tr><td colspan="2" style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#fafafa"><p><strong>Primary user interface:</strong> the app</p></td></tr><tr><th style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f7f7f7;font-weight:700"><p><strong>Pros</strong></p></th><th style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f7f7f7;font-weight:700"><p><strong>Cons</strong></p></th></tr><tr><td style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left"><ul><li>Gives the product control over the model, tools, guardrails, UI, and data flow</li><li>Keeps the user in the existing product and can use app-specific context</li><li>Useful for open-ended help or capabilities that do not fit the normal UI</li></ul></td><td style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left"><ul><li>Chat is slower than a purpose-built UI for simple, known workflows</li><li>Usually not an efficient way for the user to discover features and capabilities</li><li>Adds model cost, latency, safety, and testing burden to the app</li></ul></td></tr></tbody></table>

### Computer Use

Computer use is a broad capability that lets the LLM see and interact with the computer using screen grabs and OS-level accessibility features. Both Claude and ChatGPT have forms of Computer Use in their desktop apps.

In theory these can do anything the user can do. It is rarely faster than operating the desktop yourself. The agent needs to do continual screen grabs, interpret those screens, then move and click. Those iterations take a lot of time—and tokens.

Generating training data must be tough here vs. scraping the Internet. I am sure the frontier model vendors have farms of people clicking through apps to train these models, but there is a massive amount of visual variety to consider. This will certainly get better, but it does not seem like an efficient way for a machine to control another machine.

There are required OS-level permissions to consider which could easily scare or confuse customers:

![macOS permission dialog warning that Claude wants to bypass the system private window picker and directly access the screen and audio, with Allow and Open System Settings buttons.](https://cogint.ai/content/images/2026/07/gdoc-16TU-1pEqXCVAcK_O6Nn0fxcwP58NimVSHgHp_jIYBl8-1.png "Click to enlarge")

*Claude’s computer-use flow requires broad macOS screen-recording permission. 😱 Scary for the privacy concerned.*

#### Not much we can do to help AI Agents here

There isn’t much an app can do to specifically help the LLM in this situation. Perhaps other than running a CAPTCHA or using Cloudflare’s bot tools, there is no great way to detect if the user is an LLM. If the app is simple enough for users, hopefully it is simple enough for the LLM to interact with at a reasonable speed.

<table style="width:100%;min-width:640px;border-collapse:collapse;table-layout:fixed;white-space:normal;overflow-wrap:anywhere"><tbody><tr><td colspan="2" style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f2f3f5;font-weight:700;font-size:1.05em"><p><strong>Computer use — the agent operates the user's desktop visually</strong></p></td></tr><tr><td colspan="2" style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#fafafa"><p><strong>Primary user interface:</strong> the LLM agent, acting through the normal desktop UI</p></td></tr><tr><th style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f7f7f7;font-weight:700"><p><strong>Pros</strong></p></th><th style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f7f7f7;font-weight:700"><p><strong>Cons</strong></p></th></tr><tr><td style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left"><ul><li>Works across browsers and native apps without an app-specific integration</li><li>Can bridge several applications in one task</li><li>Provides a fallback when no API or agent interface exists</li></ul></td><td style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left"><ul><li>Slow, compute-intensive, and less reliable than structured tools</li><li>Broad OS and accessibility permissions create privacy and security concerns</li><li>UI changes, pop-ups, and ambiguous screen states can derail execution</li><li>The app developer has little control/influence beyond providing a clear, accessible UI</li></ul></td></tr></tbody></table>

### AI Browser Control

Computer Use works at the OS level. There are also a number of approaches that let the LLM interact with the browser directly:

-   Dedicated browser - OpenAI ~has~ [had](https://openai.com/index/chatgpt-for-your-most-ambitious-work/?ref=cogint.ai#:~:text=We%E2%80%99ll%20begin%20sunsetting%20the%20standalone%20Atlas%20browser%2C%20and%20will%20share%20information%20with%20users%20about%20how%20to%20transition%20to%20ChatGPT.) its own Chrome-fork called Atlas. This is now built into its Desktop App like Claude does.
-   Chrome extension — Codex and Claude have Chrome extensions.
-   Hosted virtual browser — ChatGPT’s Agent mode renders a restricted Chrome browser in the cloud with an added extension

![ChatGPT Agent mode showing a hosted Chromium window where chrome://system is blocked by organization policy and the ChatGPT Agent extension reports no access.](https://cogint.ai/content/images/2026/07/gdoc-16TU-1pEqXCVAcK_O6Nn0fxcwP58NimVSHgHp_jIYBl8-6.png "Click to enlarge")

*ChatGPT Agent’s hosted Chromium browser uses a ChatGPT Agent extension.*

The main advantage of this over Computer Use is that it can see and execute web-page code directly. Consuming a relatively small amount of text tokens is very efficient compared to interpreting images, especially when most of what is on the screen often is not immediately relevant to the task at hand. Unlike computer use, this is strictly limited to the browser, so it can’t help you with native desktop or mobile apps.

I have had decent success having AI browser control fill out long forms in the background. However, I often see it get confused on more complex UI interactions. Parsing the website’s DOM and code and iterating through many interactions can still consume a lot of tokens.

#### Detecting and adapting to AI Agents isn’t easy

I spent a little bit of time exploring if I could detect if an LLM was controlling the browser. If I could tell if it is a robot visiting, then I could render a simpler—if uglier—agent-optimized app. Unfortunately there is no great universal way to detect robot visitors. Extensions remain hidden from apps unless they want to be exposed. I did find ChatGPT’s Agent remote browser does expose a `Signature-Agent` header, so that could possibly be used if you wanted to go down the route of an agent-specific page.

One advantage of exposing the DOM is that it can contain more information than appears visually on the page. Some of the machine-readable context I added for [Generative Engine Optimization](https://en.wikipedia.org/wiki/Generative_engine_optimization?ref=cogint.ai) (GEO) could, in theory, provide additional guidance to an agent that inspects the page or follows the linked resources. Good accessibility practices should also help: descriptive ARIA labels and semantic fields such as type="tel" and aria-label="Fax destination" make the purpose of controls clearer to both assistive technologies and DOM-reading agents. My app is simple enough that I did not see much room for further optimization.

<table style="width:100%;min-width:640px;border-collapse:collapse;table-layout:fixed;white-space:normal;overflow-wrap:anywhere"><tbody><tr><td colspan="2" style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f2f3f5;font-weight:700;font-size:1.05em"><p><strong>AI browser control — the agent operates a website through the browser</strong></p></td></tr><tr><td colspan="2" style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#fafafa"><p><strong>Primary user interface:</strong> the browser plus an agent window or side panel</p></td></tr><tr><th style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f7f7f7;font-weight:700"><p><strong>Pros</strong></p></th><th style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f7f7f7;font-weight:700"><p><strong>Cons</strong></p></th></tr><tr><td style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left"><ul><li>Works with most web apps without an app-specific integration</li><li>More efficient and usually more reliable than full-screen computer use</li><li>Useful for long forms and tasks that span multiple websites</li></ul></td><td style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left"><ul><li>Limited to the browser; access to profiles, logins, and local files varies</li><li>Still slower and more brittle than structured API or tool calls</li><li>Complex widgets, pop-ups, CAPTCHAs, and DOM changes can derail the agent</li><li>The app has little control, and reliably detecting an agent is brittle</li></ul></td></tr></tbody></table>

### MCP Server

Model Context Protocol (MCP) is a standard way for an AI application to connect to external tools and data. The official [MCP specification](https://modelcontextprotocol.io/specification?ref=cogint.ai) describes a client-server model where the host is the LLM application, the client manages the connection, and the server provides capabilities such as tools, resources, and prompts.

From the app developer’s perspective, this means your app can expose a machine-readable interface for the LLM to use. Instead of asking an agent to visually click through your website, the LLM can discover a set of explicit tools and call them with structured parameters. For example, my fax app exposes functions like `start_session`, `attach_document`, `get_quote`, etc.

This is much more efficient than Computer Use or browser control. The model does not need to interpret screenshots, inspect the DOM, or guess which button to click. The app tells the model what actions are possible and what parameters are required.

The downside is that a traditional MCP server is an interface for machines with no user interface. It works well when the model needs to retrieve information or execute a clear action. If the required flow is less clear and requires several MCP tools, then the risk of the LLM messing something up increases. Fortunately this is fine for my simple fax application.

There is also a discovery problem for most users. Developers and power users can add a custom MCP server URL, but that is too much friction for many casual users. Directories, app stores, and host LLM app recommendations may help, but a new or niche app should not assume users will find and configure its MCP server on their own.

![Claude Code terminal locating the PromptFax MCP server at promptfax.app/mcp and preparing to add its Streamable HTTP endpoint to the Claude settings.](https://cogint.ai/content/images/2026/07/gdoc-16TU-1pEqXCVAcK_O6Nn0fxcwP58NimVSHgHp_jIYBl8-5.png "Click to enlarge")

*Claude Code easily discovered PromptFax’s MCP endpoint and added it to the client configuration.*

#### MCP is easy for developers

Adding an MCP server was easy for me. If your app already has a clean API, building an MCP server is often straightforward. The main work is deciding which capabilities should become tools, how those tools should be described, what authentication is needed, and how much state the server should expose back to the model.

The most important design choice is tool shape. Do not just expose every internal API endpoint. Think in terms of the typical workflows the LLM agent should execute and bundle those into MCP tools. The model should not have to assemble a dozen low-level API calls if the app already understands the workflow.

<table style="width:100%;min-width:640px;border-collapse:collapse;table-layout:fixed;white-space:normal;overflow-wrap:anywhere"><tbody><tr><td colspan="2" style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f2f3f5;font-weight:700;font-size:1.05em"><p><strong>MCP Server — structured tools and data for MCP-capable hosts</strong></p></td></tr><tr><td colspan="2" style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#fafafa"><p><strong>Primary user interface:</strong> the LLM host's chat interface</p></td></tr><tr><th style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f7f7f7;font-weight:700"><p><strong>Pros</strong></p></th><th style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f7f7f7;font-weight:700"><p><strong>Cons</strong></p></th></tr><tr><td style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left"><ul><li>Explicit, machine-readable tools are faster and more reliable than visual automation</li><li>Developer defines supported workflows, schemas, authentication, and guardrails</li><li>Reusable across MCP-capable hosts</li><li>Widely supported - ChatGPT, Claude, coding tools, and many other MCP-capable clients</li><li>Strong fit for clear backend actions, data access, and state transitions</li></ul></td><td style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left"><ul><li>Setup can be too technical for many casual users</li><li>Discovery depends on directories, recommendations, or the user already knowing the app exists</li><li>Tool-only chat is awkward for files, visual review, forms, approvals, and payment</li><li>The model still decides when and how to call tools, so tool design matters</li><li>Remote authentication, file handling, and approval behavior remain inconsistent</li></ul></td></tr></tbody></table>

### MCP Apps

I ran into the same issue with the MCP server that I originally had with my LLM prompt-driven web application. For my use case, it is much easier for a user to click through a few controls than engage in a multi-turn chat interaction. The MCP server just replicates that prompt-only interface inside the LLM where the app has no real control beyond the tools it exposes.

Fortunately a solution for this exists: MCP Apps. The MCP project introduced this as the [MCP Apps Extension](https://blog.modelcontextprotocol.io/posts/2025-11-21-mcp-apps/?ref=cogint.ai). MCP Apps start with an MCP server, but add user interface elements implemented as web widgets that are rendered inside the LLM host (Claude, ChatGPT, etc.).

The motivation for this is simple: not every app interaction should be reduced to text. As I discovered with my in-app Agent attempt, some tasks are just better executed with simple GUI controls like buttons, previews, forms, tables, etc. Without a UI layer, the model either has to describe everything in chat or the host has to invent its own way to render each tool result. That does not scale well.

MCP’s [SEP-1865](https://modelcontextprotocol.io/seps/1865-mcp-apps-interactive-user-interfaces-for-mcp?ref=cogint.ai) standardizes this. A server can declare UI resources and link them to tools. The host can render those resources in a sandboxed iframe and let the UI communicate with the host using structured messages. In plain English: the LLM can still reason and call tools, but the user can interact with an actual app surface when that is better than typing back and forth.

The important caveat is that MCP App support is not as universal as MCP server support. ChatGPT has its Apps SDK and supports MCP Apps-style embedded UIs. Claude has Connectors and also supports interactive connector experiences in some contexts. Other MCP clients may only support text and tool calls. That means an app should treat MCP Apps as progressive enhancement, not as a replacement for an MCP server.

![ChatGPT conversation showing a PDF attachment, a fax request, and the embedded PromptFax widget with document upload, destination number, and Pay & send steps.](https://cogint.ai/content/images/2026/07/gdoc-16TU-1pEqXCVAcK_O6Nn0fxcwP58NimVSHgHp_jIYBl8-2.png "Click to enlarge")

*The PromptFax MCP App embeds the main workflow as a web widget inside ChatGPT.*

#### Implementing the MCP App ✕ 3

My app evolved exactly as I outlined above, so I already had a basic UI for users and a remote MCP server. So to build this, I had to adapt my UI to a widget that fit ChatGPT’s App specs. Then I had to adapt it again to work for Claude’s MCP connector behavior. Finally, I adapted it again to fit the generic MCP Apps model as described by the [SEP-1865](https://modelcontextprotocol.io/seps/1865-mcp-apps-interactive-user-interfaces-for-mcp?ref=cogint.ai) spec. It sounds like a lot of work, but it was fast to vibe code the first iteration after I better abstracted my front end.

Handling MCP App failures did introduce some architectural challenges. For example, if a user has a file they want to use in their context history, the LLM should attempt to attach it. Unfortunately the LLM hosts do not have a reliable mechanism for uploading files to external services (ChatGPT is currently better than Claude here). If the LLM is unable to attach a file, I still need a fallback mechanism—which for me is the normal web app. To prevent users from having to completely start over, I had to share state between the MCP server, widget, and my web app. This made everything much more complex, which necessitated more testing. Then, setting up automated tests to install and use the MCP App inside ChatGPT and Claude chewed up a lot of time.

<table style="width:100%;min-width:640px;border-collapse:collapse;table-layout:fixed;white-space:normal;overflow-wrap:anywhere"><tbody><tr><td colspan="2" style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f2f3f5;font-weight:700;font-size:1.05em"><p><strong>MCP Apps — an interactive app surface backed by MCP</strong></p></td></tr><tr><td colspan="2" style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#fafafa"><p><strong>Primary user interface:</strong> LLM chat plus an app-owned embedded widget</p></td></tr><tr><th style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f7f7f7;font-weight:700"><p><strong>Pros</strong></p></th><th style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f7f7f7;font-weight:700"><p><strong>Cons</strong></p></th></tr><tr><td style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left"><ul><li>Combines model reasoning and tool calls with familiar controls, previews, and confirmations</li><li>Lets the app guide workflows in which the user and agent both participate</li><li>Better suited than chat alone to files, forms, document review, and checkout</li><li>Builds on the MCP server and can fall back to tool-only clients</li></ul></td><td style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left"><ul><li>Host support and UI capabilities differ, so portability is incomplete</li><li>Requires widget UI plus shared state and fallback paths across the host, MCP server, and web app</li><li>More implementation and automated testing than a tool-only MCP server</li><li>App-directory discovery is not guaranteed</li></ul></td></tr></tbody></table>

### WebMCP

MCP and MCP Apps assume the user starts inside an MCP client like ChatGPT, Claude, Cursor, etc. [WebMCP](https://github.com/webmachinelearning/webmcp?ref=cogint.ai) flips that around.

MCP offers server-side APIs. MCP Apps need server-hosted web widgets. [WebMCP](https://github.com/webmachinelearning/webmcp?ref=cogint.ai) is a different approach that doesn’t require a server at all. WebMCP exposes an agent-readable interface to the browser or browser-side agent. Everything stays in the browser environment. WebMCP is currently in origin trials in both [Chrome](https://developer.chrome.com/blog/ai-webmcp-origin-trial?ref=cogint.ai) and [Edge](https://developer.microsoft.com/en-us/microsoft-edge/origin-trials/trials/0b76fe60-b266-458e-a285-04e375c0c31a?ref=cogint.ai) (versions ≥ 149).

With normal browser automation, the agent has to inspect the page, infer which buttons matter, and operate the UI like a human. With WebMCP, the page can explicitly tell the agent what actions are available. In theory, the agent no longer has to guess what controls like “Submit,” “Continue,” or “Pay” do. The site can expose structured tools, prompts, and resources for interacting with the web app. The web app could use those tools to interact with some server-side component, but that is not required.

Who and what exactly will invoke WebMCP is not totally clear. Chrome has *Ask Gemini* built into the browser and Edge has the equivalent in Copilot, which loads in a side panel. These assistants, browser extensions, and other AI browsers could potentially offer to use these tools when a user visits a site that exposes them. However, it is also possible that an LLM could load a browser and use WebMCP as discussed in the AI Browser Control use case. The exact trigger, permission prompt, UI placement, and relationship to existing ChatGPT/Claude/Gemini/Copilot experiences have not been fully described.

At a minimum, I would guess that this capability will be added to the built-in Gemini in Chrome and Copilot in Edge, but who knows when.

#### Implementation

The first step was deciding what tools to expose. My exposed WebMCP tools are similar to my MCP ones, but not all the same. Items like `start_session` aren’t needed because the page load handles that. I bundled things like the destination number as a parameter in the MCP server, but I needed a dedicated tool to drive the UI element in WebMCP.

Then the Web App needs to register its tools, which is as simple as this:

```
document.modelContext.registerTool({  // note: navigator.modelContext deprecated
  name: "set_destination_number",
  inputSchema: { /* ... */ },

  execute: async (args) => {
    // code to validate the number and update the UI
  }
});
```

The hardest part is actually finding an LLM interface that uses WebMCP. Gemini in Chrome and Copilot in Edge don’t use it (at least, not yet), so you need a way to trigger the tool calls. I used the WebMCP - Model Context Tool Inspector extension by a [Google Chrome Evangelist](https://github.com/beaufortfrancois?ref=cogint.ai). This lets you invoke the WebMCP tools manually and with Gemini.

![PromptFax open beside the WebMCP Model Context Tool Inspector, which lists browser tools and shows an agent calling set_destination_number to update the fax number on the page.](https://cogint.ai/content/images/2026/07/gdoc-16TU-1pEqXCVAcK_O6Nn0fxcwP58NimVSHgHp_jIYBl8-4.png "Click to enlarge")

*The WebMCP inspector extension shows WebMCP tools and lets you invoke them with Gemini or manually.*

I noticed the LLM would sometimes hallucinate a number. For now, I will continue requiring human verification of fields before sending.

<table style="width:100%;min-width:640px;border-collapse:collapse;table-layout:fixed;white-space:normal;overflow-wrap:anywhere"><tbody><tr><td colspan="2" style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f2f3f5;font-weight:700;font-size:1.05em"><p><strong>WebMCP — structured website actions for a browser-side agent</strong></p></td></tr><tr><td colspan="2" style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#fafafa"><p><strong>Primary user interface:</strong> the website plus a browser-associated agent (still TBD)</p></td></tr><tr><th style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f7f7f7;font-weight:700"><p><strong>Pros</strong></p></th><th style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f7f7f7;font-weight:700"><p><strong>Cons</strong></p></th></tr><tr><td style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left"><ul><li>Starts from the normal website, which remains visible and authoritative</li><li>Replaces DOM/screenshot guessing with explicit, app-defined actions</li><li>Could let browser agents discover capabilities without a separate host-specific integration</li><li>Lets the developer reserve sensitive steps for explicit human confirmation</li></ul></td><td style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left"><ul><li>No mainstream end-user flow yet; invocation, permissions, and agent UI remain unsettled</li><li>Support and tooling are experimental and fragmented</li><li>Discovery benefit is still speculative and begins only after the site is reached</li><li>Dynamic tool registration and third-party scripts introduce new security concerns</li><li>Does not replace remote MCP when the task begins in a non-browser host</li></ul></td></tr></tbody></table>

### Direct API Exposure → GPTs

There is one other mechanism - exposing an API directly and hoping the LLM can figure out how to use it. Most leading LLMs have some sort of code generation capability that could navigate an [OpenAPI](https://www.openapis.org/?ref=cogint.ai) definition and then use curl or some Python code to interact with the app via an API. However, authentication makes the interaction more complicated since some back-and-forth is needed. The LLM would need some guidance on how to deal with the various interactions. That could be defined in a [SKILL.md](https://agentskills.io/home?ref=cogint.ai), but that is one more thing that needs to be installed.

None of this is a big deal for developers who do this sort of thing all the time, but it is not generally consumer-friendly—particularly in my case where use is designed to be infrequent. In addition, one of the drivers behind MCP was to solve the challenges of direct API exposure in an agent-friendly way. This problem is already addressed there.

I initially dismissed the idea of exposing another API. Then I discovered OpenAI’s “no digital services commerce” terms would not let me publicly publish my plugin. So then I looked into Custom GPTs as an alternative. Custom GPTs are basically a direct API exposure approach. Unlike Plugins, custom GPTs are easy to self-publish in ChatGPT’s public GPT directory. ChatGPT’s custom GPTs just use an OpenAPI definition, a static API key, and LLM instructions.

![ChatGPT Custom GPT editor for PromptFax showing API-key authentication, an OpenAPI actions schema and endpoints on the left, with the published GPT preview and starter prompts on the right.](https://cogint.ai/content/images/2026/07/gdoc-16TU-1pEqXCVAcK_O6Nn0fxcwP58NimVSHgHp_jIYBl8-8.png "Click to enlarge")

*A Custom GPT maps PromptFax’s OpenAPI schema to ChatGPT Actions and prompt starters.*

#### Custom GPT Implementation

This was another case of adapting the endpoints I made for the MCP server and swapping out OAuth for a static API key. You make an OpenAPI JSON file (example [here](https://promptfax.app/gpt-actions/openapi.json?ref=cogint.ai)) to describe the endpoints and set up a basic key mechanism for authentication. Custom GPTs also come with Instructions that essentially act like your system prompt. I had to do some prompt engineering to improve the flow, but nothing major.

The MCP App / Plugin is definitely a better user experience, but this custom GPT can be used by anyone with one click: [https://chatgpt.com/g/g-6a4ee7fc2f988191a9e13903e53958a0-promptfax](https://chatgpt.com/g/g-6a4ee7fc2f988191a9e13903e53958a0-promptfax?ref=cogint.ai)

<table style="width:100%;min-width:640px;border-collapse:collapse;table-layout:fixed;white-space:normal;overflow-wrap:anywhere"><tbody><tr><td colspan="2" style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f2f3f5;font-weight:700;font-size:1.05em"><p><strong>Custom GPT — LLM calls an OpenAPI-described API</strong></p></td></tr><tr><td colspan="2" style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#fafafa"><p><strong>Primary user interface: ChatGPT prompts</strong></p></td></tr><tr><th style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f7f7f7;font-weight:700"><p><strong>Pros</strong></p></th><th style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left;background:#f7f7f7;font-weight:700"><p><strong>Cons</strong></p></th></tr><tr><td style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left"><ul><li>Reuses an existing API and OpenAPI schema</li><li>Easy to implement when the application already has structured endpoints</li><li>Custom GPTs can be published in ChatGPT’s public GPT directory and opened with one click</li><li>Instructions provide lightweight guidance without building a full MCP integration</li></ul></td><td style="border:1px solid #d9d9d9;padding:12px 14px;vertical-align:top;text-align:left"><ul><li>General API use is not consumer friendly, especially when authentication requires back-and-forth</li><li>Static API keys are a poor fit for per-user authorization</li><li>Custom GPTs are specific to ChatGPT and do not carry over to other LLM hosts</li><li>Text-only interaction is awkward for files, previews, confirmations, and payment</li><li>The model must interpret the API schema and instructions, so prompt engineering and guardrails still matter</li></ul></td></tr></tbody></table>

## Conclusions

Let’s recap:

-   **In-app LLM** – trying to skip making a UI was a bad idea; with a good UI this isn’t really needed
-   **Computer use** – there is nothing special to be done here, so don’t worry about it if your UI is easy
-   **Browser use** – beef up your DOM with more info, but you should do that anyway for accessibility and GEO
-   **MCP server** – this is a critical starting point and worth doing even if it is really more developer-oriented
-   **MCP apps** – immature, but the right concept for an app like PromptFax
-   **WebMCP** – I like the concept, but it looks like we need to wait months to see exactly how this will be implemented
-   **Custom GPT** – only for ChatGPT, but this is the quickest way to publish something that works with an LLM, even if it has limited capabilities

I started this project because I was frustrated that I couldn’t find an LLM app to quickly send a fax for me. I assumed this would be easy. It was not. I did make progress on making this easier to do, but not to the level I would like yet. Unfortunately, none of these offer a seamless user experience in my situation today.

I did not discuss challenges related to file uploads and payments, which make my LLM-directed flows challenging. I look forward to experimenting with agentic commerce solutions such as [ACP](https://www.agenticcommerce.dev/?ref=cogint.ai) and [MPP](https://mpp.dev/?ref=cogint.ai) when those are more widely implemented. I’ll save this topic for a follow-up post.

I was also focused more on the “Work” persona. There are more options for the “Developer” persona. I need to publish a developer skill even if this is not at all designed for development.

So, none of this is great, but certainly there must be imminent improvements coming quickly? Then again, businesses are still requiring people to use a 30-year-old image transmission technology designed for landlines, so maybe I should adjust my expectations.
