{segments.map((segment, i) => {
if (segment.type === 'text') {
return
;
}
if (segment.type === 'tool') {
if (segment.frontendAction) {
return
;
}
return
;
}
return null;
})}
);
}
function ToolCard({ segment }) {
const isRunning = segment.status === 'running';
const isError = segment.status === 'error';
return (
{isRunning && }
{segment.tool}
{!isRunning && (isError ? : )}
{segment.args && (
{JSON.stringify(segment.args, null, 2)}
)}
{segment.result && (
{JSON.stringify(segment.result, null, 2)}
)}
{segment.error &&
{segment.error}
}
);
}
```
The tool card should be compact by default (just tool name + status icon) with collapsible sections for args and result, so it doesn't dominate the reading flow. While a tool is running (`status: 'running'`), show a spinner. When complete, show a check or error icon.
### Handling `__frontendAction` in Tool Results
When the AI calls certain tools (e.g., QR code, data view, payment, secret reveal), the tool result contains a `__frontendAction` object. This signals the frontend to render a special UI component **inline in the bubble at the tool segment's position** instead of the default collapsible ToolCard. This is already handled in the segments code above — when `segment.frontendAction` is present, render an `ActionCard` instead of a `ToolCard`.
The `extractFrontendAction` helper unwraps the action from various MCP response formats:
```js
function extractFrontendAction(result) {
if (!result) return null;
if (result.__frontendAction) return result.__frontendAction;
// Unwrap MCP wrapper format: result → result.result → content[].text → JSON
let data = result;
if (result?.result?.content) data = result.result;
if (data?.content && Array.isArray(data.content)) {
const textContent = data.content.find(c => c.type === 'text');
if (textContent?.text) {
try {
const parsed = JSON.parse(textContent.text);
if (parsed?.__frontendAction) return parsed.__frontendAction;
} catch { /* not JSON */ }
}
}
return null;
}
```
### Frontend Action Types
| Action Type | Component | Description |
|-------------|-----------|-------------|
| `qrcode` | `QrCodeActionCard` | Renders any string value as a QR code card |
| `dataView` | `DataViewActionCard` | Fetches a Business API route and renders a grid or gallery |
| `payment` | `PaymentActionCard` | "Pay Now" button that opens Stripe checkout modal |
#### QR Code Action (`type: "qrcode"`)
Triggered by the `showQrCode` MCP tool. Renders a QR code card from any string value.
```json
{
"__frontendAction": {
"type": "qrcode",
"value": "https://example.com/invite/ABC123",
"title": "Invite Link",
"subtitle": "Scan to open"
}
}
```
#### Data View Action (`type: "dataView"`)
Triggered by `showBusinessApiListInFrontEnd` or `showBusinessApiGalleryInFrontEnd`.
Frontend calls the provided Business API route using the user's bearer token, then renders:
- `viewType: "grid"` as tabular rows/columns
- `viewType: "gallery"` as image-first cards
```json
{
"__frontendAction": {
"type": "dataView",
"viewType": "grid",
"title": "Recent Orders",
"serviceName": "commerce",
"apiName": "listOrders",
"routePath": "/v1/listorders",
"httpMethod": "GET",
"queryParams": { "pageNo": 1, "pageRowCount": 10 },
"columns": [
{ "field": "id", "label": "Order ID" },
{ "field": "orderAmount", "label": "Amount", "format": "currency" }
]
}
}
```
#### Payment Action (`type: "payment"`)
Triggered by the `initiatePayment` MCP tool. Renders a payment card with amount and a "Pay Now" button.
```json
{
"__frontendAction": {
"type": "payment",
"orderId": "uuid",
"orderType": "order",
"serviceName": "commerce",
"amount": 99.99,
"currency": "USD",
"description": "Order #abc123"
}
}
```
### Conversation Management
```js
// List user's conversations
GET /api/chat/conversations
// Get conversation history
GET /api/chat/conversations/:conversationId
// Delete a conversation
DELETE /api/chat/conversations/:conversationId
```
---
## MCP Tool Discovery & Direct Invocation
The MCP BFF exposes endpoints for discovering and directly calling MCP tools (useful for debugging or building custom UIs).
### GET /api/tools — List All Tools
```js
const response = await fetch(`${mcpBffUrl}/api/tools`, { headers });
const { tools, count } = await response.json();
// tools: [{ name, description, inputSchema, service }, ...]
```
### GET /api/tools/service/:serviceName — List Service Tools
```js
const response = await fetch(`${mcpBffUrl}/api/tools/service/commerce`, { headers });
const { tools } = await response.json();
```
### POST /api/tools/call — Call a Tool Directly
```js
const response = await fetch(`${mcpBffUrl}/api/tools/call`, {
method: 'POST',
headers,
body: JSON.stringify({
toolName: "listProducts",
args: { page: 1, limit: 10 },
}),
});
const result = await response.json();
```
### GET /api/tools/status — Connection Status
```js
const status = await fetch(`${mcpBffUrl}/api/tools/status`, { headers });
// Returns health of each MCP service connection
```
### POST /api/tools/refresh — Reconnect Services
```js
await fetch(`${mcpBffUrl}/api/tools/refresh`, { method: 'POST', headers });
// Reconnects to all MCP services and refreshes the tool registry
```
---
## Elasticsearch API
The MCP BFF provides direct access to Elasticsearch for searching, filtering, and aggregating data across all project indices.
All Elasticsearch endpoints are under `/api/elastic`.
### GET /api/elastic/allIndices — List Project Indices
Returns all Elasticsearch indices belonging to this project (prefixed with `airbnb3_`).
```js
const indices = await fetch(`${mcpBffUrl}/api/elastic/allIndices`, { headers });
// ["airbnb3_products", "airbnb3_orders", ...]
```
### POST /api/elastic/:indexName/rawsearch — Raw Elasticsearch Query
Execute a raw Elasticsearch query on a specific index.
```js
const response = await fetch(`${mcpBffUrl}/api/elastic/products/rawsearch`, {
method: 'POST',
headers,
body: JSON.stringify({
query: {
bool: {
must: [
{ match: { status: "active" } },
{ range: { price: { gte: 10, lte: 100 } } }
]
}
},
size: 20,
from: 0,
sort: [{ createdAt: "desc" }]
}),
});
const { total, hits, aggregations, took } = await response.json();
// hits: [{ _id, _index, _score, _source: { ...document... } }, ...]
```
Note: The index name is automatically prefixed with `airbnb3_` if not already prefixed.
### POST /api/elastic/:indexName/search — Simplified Search
A higher-level search API with built-in support for filters, sorting, and pagination.
```js
const response = await fetch(`${mcpBffUrl}/api/elastic/products/search`, {
method: 'POST',
headers,
body: JSON.stringify({
search: "wireless headphones", // Full-text search
filters: { status: "active" }, // Field filters
sort: { field: "createdAt", order: "desc" },
page: 1,
limit: 25,
}),
});
```
### POST /api/elastic/:indexName/aggregate — Aggregations
Run aggregation queries for analytics and dashboards.
```js
const response = await fetch(`${mcpBffUrl}/api/elastic/orders/aggregate`, {
method: 'POST',
headers,
body: JSON.stringify({
aggs: {
status_counts: { terms: { field: "status.keyword" } },
total_revenue: { sum: { field: "amount" } },
monthly_orders: {
date_histogram: { field: "createdAt", calendar_interval: "month" }
}
},
query: { range: { createdAt: { gte: "now-1y" } } }
}),
});
```
### GET /api/elastic/:indexName/mapping — Index Mapping
Get the field mapping for an index (useful for building dynamic filter UIs).
```js
const mapping = await fetch(`${mcpBffUrl}/api/elastic/products/mapping`, { headers });
```
### POST /api/elastic/:indexName/ai-search — AI-Assisted Search
Uses the configured AI model to convert a natural-language query into an Elasticsearch query.
```js
const response = await fetch(`${mcpBffUrl}/api/elastic/orders/ai-search`, {
method: 'POST',
headers,
body: JSON.stringify({
query: "orders over $100 from last month that are still pending",
}),
});
// Returns: { total, hits, generatedQuery, ... }
```
---
## Log API
The MCP BFF provides log viewing endpoints for monitoring application behavior.
### GET /api/logs — Query Logs
```js
const response = await fetch(`${mcpBffUrl}/api/logs?page=1&limit=50&logType=2&service=commerce&search=payment`, {
headers,
});
```
**Query Parameters:**
- `page` — Page number (default: 1)
- `limit` — Items per page (default: 50)
- `logType` — 0=INFO, 1=WARNING, 2=ERROR
- `service` — Filter by service name
- `search` — Search in subject and message
- `from` / `to` — Date range (ISO strings)
- `requestId` — Filter by request ID
### GET /api/logs/stream — Real-time Console Stream (SSE)
Streams real-time console output from all services via Server-Sent Events.
```js
const eventSource = new EventSource(`${mcpBffUrl}/api/logs/stream?services=commerce,auth`, {
headers: { 'Authorization': `Bearer ${accessToken}` },
});
eventSource.addEventListener('log', (event) => {
const logEntry = JSON.parse(event.data);
// { service, timestamp, level, message, ... }
});
```
---
## Available Services
The MCP BFF connects to the following backend services:
| Service | Description |
|---------|-------------|
| `auth` | Authentication, user management, sessions |
| `messaging` | Enables secure in-app messaging between guests and hosts. Handles threads, messages (with text/media/system types), abuse flagging, and admin moderation for resolution.. |
| `propertyCatalog` | Service for management of property listings, calendars, amenities, and localization for a short-term rental marketplace. Hosts can manage listings, availability, multi-language descriptions, policies, pricing, and attributes, served for global search and discovery... |
| `bookingManagement` | Orchestrates booking, payment, calendar, changewsand dispute flows for Airbnb-style short-term rental marketplace...test Handles reservations, approval, Stripe payments, iCal sync, payment records, and the dispute/refund lifecycle with host/guest/admin visibility. |
| `reviewSystem` | Handles double-blind, moderated reviews and rating aggregation for stays. Allows guests/hosts to review each other and listings, supports moderation, and exposes aggregate stats for listings/profiles... |
| `platformAdmin` | Administrative and compliance management backend for moderation, audit, dispute, financial oversight, localization, and GDPR in the Airbnb-style rental platform. |
| `agentHub` | AI Agent Hub |
Each service exposes MCP tools that the AI can call through the BFF. Use `GET /api/tools` to discover all available tools at runtime, or `GET /api/tools/service/:serviceName` to list tools for a specific service.
---
## MCP as Internal API Gateway
The MCP-BFF service can also be used by the frontend as an **internal API gateway** for tool-based interactions. This is separate from external AI tool connections — it is meant for frontend code that needs to call backend tools programmatically.
### Direct Tool Calls (REST)
Use the REST tool invocation endpoints for programmatic access from frontend code:
```js
// List all available tools
const tools = await fetch(`${mcpBffUrl}/api/tools`, { headers });
// Call a specific tool directly
const result = await fetch(`${mcpBffUrl}/api/tools/call`, {
method: 'POST',
headers,
body: JSON.stringify({
toolName: 'listProducts',
args: { page: 1, limit: 10 },
}),
});
```
### AI-Orchestrated Calls (Chat API)
For AI-driven interactions, use the chat streaming API documented above (`POST /api/chat/stream`). The AI model decides which tools to call based on the user's message.
Both approaches use the user's JWT access token for authentication — the MCP-BFF forwards it to the correct backend service.
---
## MCP Connection Info for Profile Page
The user's **profile page** should include an informational section explaining how to connect external AI tools (Cursor, Claude Desktop, Lovable, Windsurf, etc.) to this application's backend via MCP.
### What to Display
The MCP-BFF exposes a **unified MCP endpoint** that aggregates tools from all backend services into a single connection point:
| Environment | URL |
|-------------|-----|
| **Preview** | `https://airbnb3.prw.mindbricks.com/mcpbff-api/mcp` |
| **Staging** | `https://airbnb3-stage.mindbricks.co/mcpbff-api/mcp` |
| **Production** | `https://airbnb3.mindbricks.co/mcpbff-api/mcp` |
For legacy MCP clients that don't support StreamableHTTP, an SSE fallback is available at the same URL with `/sse` appended (e.g., `.../mcpbff-api/mcp/sse`).
### Profile Page UI Requirements
Add an **"MCP Connection"** or **"Connect External AI Tools"** card/section to the profile page with:
1. **Endpoint URL** — Display the MCP endpoint URL for the current environment with a copy-to-clipboard button.
2. **Ready-to-Copy Configs** — Show copy-to-clipboard config snippets for popular tools:
**Cursor** (`.cursor/mcp.json`):
```json
{
"mcpServers": {
"airbnb3": {
"url": "https://airbnb3.prw.mindbricks.com/mcpbff-api/mcp",
"headers": {
"Authorization": "Bearer your_access_token_here"
}
}
}
}
```
**Claude Desktop** (`claude_desktop_config.json`):
```json
{
"mcpServers": {
"airbnb3": {
"url": "https://airbnb3.prw.mindbricks.com/mcpbff-api/mcp",
"headers": {
"Authorization": "Bearer your_access_token_here"
}
}
}
}
```
3. **Auth Note** — Note that users should replace `your_access_token_here` with a valid JWT access token from the login API.
4. **OAuth Note** — Display a note that OAuth authentication is not currently supported for MCP connections.
5. **Available Tools** — Optionally show a summary of available tool categories (e.g., "CRUD operations for all data objects, custom business APIs, file operations") or link to the tools discovery endpoint (`GET /api/tools`).
---
**After this prompt, the user may give you new instructions to update the output of this prompt or provide subsequent prompts about the project.**
---