import { Tool, ToolContext } from '@frontmcp/sdk';
import { card, badge, button, descriptionList } from '@frontmcp/ui';
import { z } from 'zod';
const inputSchema = {
orderId: z.string().describe('Order ID to look up'),
};
const outputSchema = z.object({
id: z.string(),
status: z.enum(['pending', 'processing', 'shipped', 'delivered']),
customer: z.object({
name: z.string(),
email: z.string(),
}),
items: z.array(z.object({
name: z.string(),
quantity: z.number(),
price: z.number(),
})),
total: z.number(),
createdAt: z.string(),
trackingUrl: z.string().optional(),
});
type OrderOutput = z.infer<typeof outputSchema>;
@Tool({
name: 'get_order',
description: 'Retrieve order details by ID',
inputSchema,
outputSchema,
annotations: {
title: 'Order Lookup',
readOnlyHint: true,
},
ui: {
template: (ctx) => {
const { output, helpers } = ctx;
const statusVariants = {
pending: 'warning',
processing: 'info',
shipped: 'primary',
delivered: 'success',
} as const;
const itemRows = output.items.map(item => `
<tr>
<td class="py-2">${helpers.escapeHtml(item.name)}</td>
<td class="py-2 text-center">${item.quantity}</td>
<td class="py-2 text-right">${helpers.formatCurrency(item.price)}</td>
</tr>
`).join('');
return card(`
<div class="flex items-center justify-between mb-4">
<div>
<p class="text-sm text-gray-500">Order ID</p>
<p class="font-mono">${helpers.escapeHtml(output.id)}</p>
</div>
${badge(output.status.charAt(0).toUpperCase() + output.status.slice(1), {
variant: statusVariants[output.status],
})}
</div>
<div class="border-t border-b py-4 my-4">
${descriptionList([
{ term: 'Customer', description: helpers.escapeHtml(output.customer.name) },
{ term: 'Email', description: helpers.escapeHtml(output.customer.email) },
{ term: 'Order Date', description: helpers.formatDate(output.createdAt) },
])}
</div>
<table class="w-full">
<thead>
<tr class="border-b">
<th class="py-2 text-left">Item</th>
<th class="py-2 text-center">Qty</th>
<th class="py-2 text-right">Price</th>
</tr>
</thead>
<tbody>${itemRows}</tbody>
<tfoot>
<tr class="border-t font-bold">
<td colspan="2" class="py-2">Total</td>
<td class="py-2 text-right">${helpers.formatCurrency(output.total)}</td>
</tr>
</tfoot>
</table>
`, {
title: 'Order Details',
footer: output.trackingUrl
? button('Track Shipment', { href: output.trackingUrl, target: '_blank' })
: undefined,
});
},
displayMode: 'inline',
widgetDescription: 'Displays order details including items, customer info, and status',
invocationStatus: {
invoking: 'Looking up order...',
invoked: 'Order found',
},
},
})
export class GetOrderTool extends ToolContext<typeof inputSchema, typeof outputSchema> {
async execute(input: { orderId: string }): Promise<OrderOutput> {
// Fetch order from database...
return {
id: input.orderId,
status: 'shipped',
customer: { name: 'John Doe', email: '[email protected]' },
items: [
{ name: 'Widget Pro', quantity: 2, price: 49.99 },
{ name: 'Widget Basic', quantity: 1, price: 29.99 },
],
total: 129.97,
createdAt: new Date().toISOString(),
trackingUrl: 'https://tracking.example.com/12345',
};
}
}