Skip to main content
Cashfree HERE is a React-based payment plugin built on the Model Context Protocol (MCP) Apps standard. It renders interactive payment widgets directly inside AI chat interfaces, letting users pay with UPI (GPay, PhonePe, Paytm, BHIM), QR codes, or cards—all without exposing sensitive payment data to the AI model.

Understanding Model Context Protocol Apps

An MCP (Model Context Protocol) App is an application that communicates with AI hosts (such as Claude Desktop, ChatGPT, and VS Code Copilot) through a standardised protocol. MCP defines how AI models discover and use tools (actions), resources (data and UI), and prompts (templates). A standard MCP server exposes tools that return text. An MCP App extends this capability by serving interactive UI widgets as resources. When the AI invokes a tool, the host renders a rich widget (HTML/React) inline within the chat, enabling experiences such as payment forms, booking interfaces, and dashboards.

How Model Context Protocol Apps work

How MCP Apps work

Key concepts

The core MCP concepts are defined in the following table:
ConceptDescription
MCP serverA service that exposes tools and resources over the MCP protocol (stdio or HTTP transport).
ToolA function that the AI model can invoke. It takes structured input and returns structured output.
ResourceA piece of data or UI (HTML widget) that the host can render. Resources use URIs such as ui://widget/booking.html.
WidgetAn HTML/React application served as a resource. It renders interactively inside the AI chat interface.
TransportThe method by which the AI host communicates with the MCP server: stdio (local) or StreamableHTTP (remote/hosted).
Refer the following resources for additional information about the MCP standard:

Create your own Model Context Protocol App

To build an MCP App that renders UI widgets in AI chats, complete the following steps:
1

Create an MCP server using `@modelcontextprotocol/sdk`

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";

const server = new McpServer({ name: "my-app", version: "1.0.0" });
2

Register a UI resource (your widget HTML)

server.registerResource(
  "my-widget",
  "ui://widget/app.html",
  { description: "My interactive widget", mimeType: "text/html;profile=mcp-app" },
  async () => ({
    contents: [{
      uri: "ui://widget/app.html",
      mimeType: "text/html;profile=mcp-app",
      text: "<html>...</html>", // Your bundled React/HTML widget
    }],
  })
);
3

Register tools that reference the widget

server.registerTool("my_action", {
  description: "Perform an action",
  inputSchema: { query: z.string() },
  _meta: {
    "openai/outputTemplate": "ui://widget/app.html",
    ui: { resourceUri: "ui://widget/app.html" },
  },
}, async (args) => {
  return {
    content: [{ type: "text", text: "" }],
    _meta: { /* data for your widget */ },
  };
});
4

Serve over HTTP for remote access (ChatGPT, Claude, and other MCP Apps hosts)

import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
// Handle POST /mcp with StreamableHTTPServerTransport
Cashfree HERE handles all of this for the payment widget. You only need to register it on your server.

Cashfree payment plugin

The @cashfreepayments/cashfree-here npm package provides pre-built payment tools and a React payment widget. You register them on your MCP server, and the AI host renders the payment UI when the tool is invoked.

Supported payment methods

The plugin supports the following payment methods:
MethodDescription
UPI IntentLaunches GPay, PhonePe, Paytm, or BHIM directly on mobile.
UPI QR CodeDisplays a scannable QR code for UPI payment.
CardsAllows payment with credit or debit cards, including saved cards for one-tap checkout (PCI-DSS compliant).
ReservePayComing soon.
Cashfree PayComing soon.

Security

The payment widget implements the following security measures:
  • Card details are handled entirely client-side within the widget.
  • No sensitive payment data is sent to the AI model.
  • Cashfree handles card processing (PCI-DSS compliant).
  • Three-D Secure (3D Secure) is supported for card payments.
  • Cards are stored and managed by using Cashfree’s instrument vault.

Prerequisites

Before you begin, ensure that you have the following prerequisites:

Installation

Install the package by using one of the following package managers:
npm install @cashfreepayments/cashfree-here

Usage

The plugin exports three functions that you register on your MCP server. The following table describes each export:
ExportPurpose
registerCashfreeWidgetRegisters the payment widget as an MCP resource.
cashfreeUpiToolRegisters the UPI payment tool (intent and QR code).
cashfreeCardPaymentToolRegisters the card payment tool.
You can register them in two ways: by using the MCP ext-apps helpers or by using the standard MCP SDK directly. Both approaches work with any MCP Apps host, including ChatGPT and Claude.
Use registerAppResource and registerAppTool from @modelcontextprotocol/ext-apps/server for automatic MCP Apps metadata handling.
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import {
  registerAppResource,
  registerAppTool,
} from "@modelcontextprotocol/ext-apps/server";
import {
  registerCashfreeWidget,
  cashfreeUpiTool,
  cashfreeCardPaymentTool,
} from "@cashfreepayments/cashfree-here";

const server = new McpServer({
  name: "My Payment Server",
  version: "1.0.0",
});

// 1. Register the Payment Widget Resource
registerAppResource(
  server,
  ...registerCashfreeWidget({ widgetBaseUrl: "https://your-server.com" })
);

// 2. Register Payment Tools
registerAppTool(server, ...cashfreeUpiTool({ environment: "production" }));
registerAppTool(
  server,
  ...cashfreeCardPaymentTool({
    environment: "production",
    clientId: process.env.CASHFREE_CLIENT_ID!,
    clientSecret: process.env.CASHFREE_CLIENT_SECRET!,
  })
);

Configuration

The configuration interface for the Cashfree tools is defined as follows:
interface CashfreeToolConfig {
  environment: "sandbox" | "production";
  clientId?: string;    // Required only for card payments
  clientSecret?: string; // Required only for card payments
}
The following table describes each configuration parameter:
ParameterRequiredDescription
environmentYesSpecify "sandbox" for testing or "production" for live payments.
clientIdFor cardsYour Cashfree App ID. Required only for cashfreeCardPaymentTool.
clientSecretFor cardsYour Cashfree Secret Key. Required only for cashfreeCardPaymentTool.

Tool input schemas

The following sections define the input schemas for each tool: UpiTool
{
  paymentSessionId: string;       // Cashfree payment session ID (from order creation)
  paymentApp?: "bhim" | "gpay" | "paytm" | "phonepe" | "qr";  // Optional preferred UPI method
}
CardPaymentTool
{
  paymentSessionId: string;  // Cashfree payment session ID
  customerId: string;        // Customer ID to fetch saved cards for one-tap checkout
}

Environment variables

Configure the following environment variables:
CASHFREE_CLIENT_ID=your_client_id
CASHFREE_CLIENT_SECRET=your_client_secret

Example: Good Food restaurant booking app

The Good Food app demonstrates a complete real-world integration: a restaurant table booking system with Cashfree HERE payments, running as an MCP App inside AI interfaces such as ChatGPT and Claude.

What it does

The app follows this workflow:
  1. The user asks to find restaurants in Mumbai.
  2. The AI host invokes search_restaurants. The widget displays restaurant listings with images, ratings, and prices.
  3. The user selects a restaurant and books a table.
  4. The widget creates a Cashfree order and receives a paymentSessionId.
  5. The AI host invokes UpiTool or CardPaymentTool with the session ID. The payment widget renders inline.
  6. The user completes payment by using UPI or a card.
  7. The booking is confirmed.

How it integrates payment tools

The server registers Cashfree HERE alongside its own app-specific tools:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import {
  cashfreeUpiTool,
  cashfreeCardPaymentTool,
  registerCashfreeWidget,
} from "@cashfreepayments/cashfree-here";

const SERVER_URL = process.env.SERVER_URL || "http://localhost:8787";

function createGoodFoodServer() {
  const server = new McpServer({ name: "good-food", version: "1.0.0" });

  // Register Cashfree HERE payment widget
  server.registerResource(
    ...registerCashfreeWidget({ widgetBaseUrl: SERVER_URL })
  );

  // Register Cashfree HERE payment tools
  server.registerTool(...cashfreeUpiTool({ environment: "production" }));
  server.registerTool(
    ...cashfreeCardPaymentTool({
      environment: "production",
      clientId: process.env.CASHFREE_CLIENT_ID!,
      clientSecret: process.env.CASHFREE_CLIENT_SECRET!,
    })
  );

  // Register app-specific tools
  server.registerTool("search_restaurants", {
    title: "Search Restaurants",
    description: "Search for restaurants by city",
    inputSchema: { city: z.string().min(1) },
  }, async (args) => {
    const restaurants = await fetchRestaurants(args.city);
    return {
      content: [{ type: "text", text: "" }],
      _meta: { restaurants, apiBaseUrl: SERVER_URL },
    };
  });

  return server;
}

Payment flow

The widget creates a Cashfree order by making a direct API call to the server, which returns a paymentSessionId. This session ID is then passed to the Cashfree HERE payment tools. The following example shows how to create a Cashfree order:
// Server-side: API endpoint that the widget calls to create a Cashfree order
// POST /api/create-order
const response = await fetch("https://api.cashfree.com/pg/orders", {
  method: "POST",
  headers: {
    "x-client-id": CASHFREE_CLIENT_ID,
    "x-client-secret": CASHFREE_CLIENT_SECRET,
    "Content-Type": "application/json",
    "x-api-version": "2025-01-01",
  },
  body: JSON.stringify({
    order_amount: totalAmount,
    order_currency: "INR",
    order_id: orderId,
    customer_details: {
      customer_id: "user_123",
      customer_phone: "9876543210",
    },
  }),
});

const { payment_session_id } = await response.json();
// This paymentSessionId is passed to UpiTool or CardPaymentTool

Architecture

Good Food architecture

Building a custom payment host

If you are building your own AI-powered product (such as your own chat interface, assistant, or custom platform), you aren’t limited to ChatGPT or Claude. You can build a custom host that connects to your MCP server and renders the Cashfree HERE payment widget directly in your interface. To support Cashfree HERE (and MCP Apps in general) in your own host, your platform must complete the following tasks:
1

Connect to the MCP server

Connect to the MCP server by using HTTP and StreamableHTTPServerTransport. Discover its tools and resources.
2

Detect UI resources

Detect UI resources. When a tool result references a resource with mimeType: "text/html;profile=mcp-app", treat it as a widget.
3

Render the widget in a sandboxed iframe

Render the widget in a sandboxed iframe. Pass tool arguments and results into the iframe by using postMessage, following the MCP Apps messaging protocol.
4

Proxy tool calls from the widget

Proxy tool calls from the widget. The widget may invoke further MCP tools (such as UpiTool) from within the iframe. Your host must relay these calls back to the MCP server.
The MCP Apps extension defines the full host-side protocol. This includes how the iframe is initialised, how tool data is delivered, and how bidirectional messaging works.

Reference host implementation

The MCP Apps team provides a basic-host reference implementation in the official ext-apps repository. It’s a minimal working example of an MCP Apps host. It connects to any MCP server, calls tools, and renders widget UIs in sandboxed iframes. Use it as a starting point for your own platform.

Using @mcp-ui/client

If your platform is React-based, the @mcp-ui/client package provides ready-made React components for rendering MCP Apps views. It handles the iframe sandboxing, postMessage protocol, and tool result delivery. You don’t have to implement the host protocol from scratch. To install the package, run the following command:
npm install @mcp-ui/client
MCP Apps widgets run in a sandboxed iframe. They can’t access your parent page, cookies, or DOM. This security model makes it safe to embed third-party MCP App widgets, including Cashfree HERE, in your own product.

Resources