Documentation Index Fetch the complete documentation index at: https://docs.agentfront.dev/llms.txt
Use this file to discover all available pages before exploring further.
Beyond tools, FrontMCP supports prompts (reusable LLM instructions) and resources (data that LLMs can read). This guide shows you how to create and combine them with tools for powerful workflows.
What You’ll Build
An expense management app with:
A prompt that generates expense reports
A resource template that fetches expense details by ID
A static resource that returns expense policies
Prompts
Prompts provide pre-built instructions that LLMs can use. They’re perfect for consistent formatting, complex workflows, or domain-specific guidance.
Creating a Basic Prompt
import { Prompt , PromptContext } from ' @frontmcp/sdk ' ;
@ Prompt ({
name : ' expense-report ' ,
description : ' Generate an expense report summary for a given time period ' ,
arguments : [
{
name : ' startDate ' ,
description : ' Start date for the report (YYYY-MM-DD) ' ,
required : true ,
},
{
name : ' endDate ' ,
description : ' End date for the report (YYYY-MM-DD) ' ,
required : true ,
},
{
name : ' category ' ,
description : ' Optional expense category filter ' ,
required : false ,
},
],
})
export default class ExpenseReportPrompt extends PromptContext {
async execute ( args : Record < string , string >) {
const { startDate , endDate , category } = args ;
const categoryFilter = category ? ` for category " ${ category } " ` : '' ;
return {
description : ` Expense report from ${ startDate } to ${ endDate }${ categoryFilter } ` ,
messages : [
{
role : ' user ' as const ,
content : {
type : ' text ' as const ,
text : ` Please generate an expense report summary for the period from ${ startDate } to ${ endDate }${ categoryFilter } .
Include the following information:
1. Total expenses for the period
2. Breakdown by category
3. Top 5 largest expenses
4. Comparison with previous period (if available)
5. Any anomalies or unusual spending patterns
Format the report in a clear, professional manner suitable for management review. ` ,
},
},
],
};
}
}
Prompt Arguments
Define the inputs your prompt accepts:
arguments : [
{
name : ' startDate ' ,
description : ' Start date (YYYY-MM-DD) ' ,
required : true , // Must be provided
},
{
name : ' format ' ,
description : ' Output format ' ,
required : false , // Optional
},
]
Prompt Return Value
Prompts return an object with:
Property Type Description descriptionstringHuman-readable summary of the prompt messagesPromptMessage[]Array of messages to send to the LLM
Each message has:
role: 'user' or 'assistant'
content: Object with type: 'text' and text: string
Resources
Resources expose data that LLMs can read. There are two types:
Static Resources
Fixed content at a specific URI:
import { Resource , ResourceContext } from ' @frontmcp/sdk ' ;
import { ReadResourceResult } from ' @modelcontextprotocol/sdk/types.js ' ;
@ Resource ({
name : ' expense-policy ' ,
uri : ' expense://policy ' ,
description : ' Company expense policy guidelines ' ,
mimeType : ' text/markdown ' ,
})
export default class ExpensePolicyResource extends ResourceContext {
async execute (): Promise < ReadResourceResult > {
return {
contents : [
{
uri : ' expense://policy ' ,
mimeType : ' text/markdown ' ,
text : ` # Expense Policy
## Eligible Expenses
- Travel (flights, hotels, ground transportation)
- Meals during business travel
- Client entertainment (with prior approval)
- Office supplies
- Professional development
## Limits
- Meals: $75/day domestic, $100/day international
- Hotels: Must use preferred vendors
- Flights: Economy class for trips under 6 hours
## Approval Requirements
- Under $500: Manager approval
- $500-$2000: Director approval
- Over $2000: VP approval
## Submission Deadline
All expenses must be submitted within 30 days of incurrence. ` ,
},
],
};
}
}
Resource Templates
Dynamic resources with URI parameters:
import { ResourceTemplate , ResourceContext } from ' @frontmcp/sdk ' ;
import { ReadResourceResult } from ' @modelcontextprotocol/sdk/types.js ' ;
type ExpenseParams = {
expenseId : string ;
};
@ ResourceTemplate ({
name : ' expense-by-id ' ,
uriTemplate : ' expense://expenses/{expenseId} ' ,
description : ' Get expense details by ID ' ,
mimeType : ' application/json ' ,
})
export default class ExpenseByIdResource extends ResourceContext < ExpenseParams > {
async execute ( uri : string , params : ExpenseParams ): Promise < ReadResourceResult > {
const { expenseId } = params ;
// In production, fetch from database
const expense = {
id : expenseId ,
description : ` Business expense # ${ expenseId } ` ,
amount : 150.00 ,
currency : ' USD ' ,
category : ' Travel ' ,
status : ' approved ' ,
submittedBy : ' john.doe@company.com ' ,
submittedAt : new Date (). toISOString (),
};
return {
contents : [
{
uri ,
mimeType : ' application/json ' ,
text : JSON . stringify ( expense , null , 2 ),
},
],
};
}
}
The {expenseId} in the URI template becomes a parameter passed to execute().
Combining Everything in an App
Register prompts and resources alongside tools:
import { App } from ' @frontmcp/sdk ' ;
// Tools
import CreateExpenseTool from ' ./tools/create-expense.tool ' ;
import GetExpenseTool from ' ./tools/get-expense.tool ' ;
// Prompts
import ExpenseReportPrompt from ' ./prompts/expense-report.prompt ' ;
import CategorizeExpensePrompt from ' ./prompts/categorize-expense.prompt ' ;
// Resources
import ExpensePolicyResource from ' ./resources/expense-policy.resource ' ;
import ExpenseByIdResource from ' ./resources/expense-by-id.resource ' ;
import ExpenseCategoriesResource from ' ./resources/expense-categories.resource ' ;
@ App ({
id : ' expense ' ,
name : ' Expense Management App ' ,
tools : [ CreateExpenseTool , GetExpenseTool ],
prompts : [ ExpenseReportPrompt , CategorizeExpensePrompt ],
resources : [ ExpensePolicyResource , ExpenseByIdResource , ExpenseCategoriesResource ],
})
export default class ExpenseApp {}
Example: Categorization Prompt
Here’s a prompt that helps LLMs categorize expenses:
import { Prompt , PromptContext } from ' @frontmcp/sdk ' ;
@ Prompt ({
name : ' categorize-expense ' ,
description : ' Help categorize an expense based on its description ' ,
arguments : [
{
name : ' description ' ,
description : ' The expense description to categorize ' ,
required : true ,
},
{
name : ' amount ' ,
description : ' The expense amount ' ,
required : false ,
},
],
})
export default class CategorizeExpensePrompt extends PromptContext {
async execute ( args : Record < string , string >) {
const { description , amount } = args ;
const amountContext = amount ? ` (Amount: $ ${ amount } ) ` : '' ;
return {
description : ` Categorize expense: " ${ description } " ` ,
messages : [
{
role : ' user ' as const ,
content : {
type : ' text ' as const ,
text : ` Please categorize the following expense ${ amountContext } :
" ${ description } "
Choose from these categories:
- Travel (flights, hotels, transportation)
- Meals (food and beverages)
- Entertainment (client dinners, events)
- Office Supplies (equipment, materials)
- Software (subscriptions, licenses)
- Professional Development (training, conferences)
- Other
Respond with:
1. The recommended category
2. A brief explanation for your choice
3. Any flags if this expense might need special approval ` ,
},
},
],
};
}
}
Example: Categories Resource
A static resource listing available categories:
import { Resource , ResourceContext } from ' @frontmcp/sdk ' ;
import { ReadResourceResult } from ' @modelcontextprotocol/sdk/types.js ' ;
@ Resource ({
name : ' expense-categories ' ,
uri : ' expense://categories ' ,
description : ' List of available expense categories ' ,
mimeType : ' application/json ' ,
})
export default class ExpenseCategoriesResource extends ResourceContext {
async execute (): Promise < ReadResourceResult > {
const categories = [
{ id : ' travel ' , name : ' Travel ' , description : ' Flights, hotels, transportation ' },
{ id : ' meals ' , name : ' Meals ' , description : ' Food and beverages during business ' },
{ id : ' entertainment ' , name : ' Entertainment ' , description : ' Client dinners, events ' },
{ id : ' office ' , name : ' Office Supplies ' , description : ' Equipment and materials ' },
{ id : ' software ' , name : ' Software ' , description : ' Subscriptions and licenses ' },
{ id : ' training ' , name : ' Professional Development ' , description : ' Training, conferences ' },
];
return {
contents : [
{
uri : ' expense://categories ' ,
mimeType : ' application/json ' ,
text : JSON . stringify ( categories , null , 2 ),
},
],
};
}
}
File Organization
Recommended structure:
src/apps/expense/
├── index.ts # App definition
├── tools/
│ ├── create-expense.tool.ts
│ └── get-expense.tool.ts
├── prompts/
│ ├── index.ts # Re-exports
│ ├── expense-report.prompt.ts
│ └── categorize-expense.prompt.ts
└── resources/
├── index.ts # Re-exports
├── expense-policy.resource.ts
├── expense-by-id.resource.ts
└── expense-categories.resource.ts
Use barrel exports in index.ts files:
// prompts/index.ts
export { default as ExpenseReportPrompt } from ' ./expense-report.prompt ' ;
export { default as CategorizeExpensePrompt } from ' ./categorize-expense.prompt ' ;
Best Practices
Use clear, descriptive names
Names should indicate what the prompt/resource does: // Good
name : ' expense-report '
name : ' categorize-expense '
uri : ' expense://expenses/{expenseId} '
// Bad
name : ' prompt1 '
name : ' helper '
uri : ' data://item/{id} '
Provide detailed descriptions
Help LLMs understand when to use each prompt/resource: description : ' Generate an expense report summary for a given time period, including totals, breakdowns, and anomaly detection '
Use appropriate MIME types
Match the content type:
text/markdown for formatted text
application/json for structured data
text/plain for simple text
Validate URI template parameters
Add validation in your execute method: async execute ( uri : string , params : { expenseId : string }) {
if (! params . expenseId || params . expenseId . length < 1 ) {
throw new Error ( ' Invalid expense ID ' );
}
// ...
}
Next Steps
Role-Based Authorization Control access to prompts and resources
Prompts Reference Full @Prompt decorator documentation
Resources Reference Full @Resource decorator documentation
Testing Test prompts and resources