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.
Basic Usage
import { Tool , ToolContext } from ' @frontmcp/sdk ' ;
import { z } from ' @frontmcp/sdk ' ;
@ Tool ({
name : ' get_weather ' ,
description : ' Get current weather for a location ' ,
inputSchema : {
city : z . string (). describe ( ' City name ' ),
units : z . enum ([ ' celsius ' , ' fahrenheit ' ]). default ( ' celsius ' ),
},
})
class GetWeatherTool extends ToolContext {
async execute ( input : { city : string ; units : ' celsius ' | ' fahrenheit ' }) {
const weather = await fetchWeather ( input . city , input . units );
return { temperature : weather . temp , conditions : weather . conditions };
}
}
Signature
function Tool < I extends ZodRawShape , O extends OutputSchema >(
opts : ToolMetadataOptions < I , O >
): TypedClassDecorator
Type Safety
The @Tool decorator provides compile-time type checking:
Input validation : The execute() parameter type must exactly match the inputSchema. Mismatches produce a descriptive error at compile time.
Output validation : When outputSchema is provided, the execute() return type must be assignable to the inferred output type.
Context check : The decorated class must extend ToolContext. Using @Tool on a plain class produces a compile error.
Invalid options : Typos in decorator options (e.g., concurrency: { maxConcurrensst: 5 }) are caught at compile time with specific error messages, without losing autocomplete on other fields.
// Compile error: parameter type { query: number } doesn't match inputSchema { query: string }
@ Tool ({ name : ' search ' , inputSchema : { query : z . string () } })
class BadTool extends ToolContext {
async execute ( input : { query : number }) { // TS error on this class
return { result : input . query };
}
}
Configuration Options
Required Properties
Property Type Description namestringUnique tool identifier inputSchemaZodShapeZod object shape for input validation
Optional Properties
Property Type Description descriptionstringTool description for AI outputSchemaZodTypeOutput validation schema idstringStable identifier for tracking tagsstring[]Categorization tags visibility'public' | 'hidden' | 'internal'Discovery visibility. hidden hides from public lists; internal keeps it for in-process callers only rateLimitRateLimitConfigPer-tool rate limit (maxRequests, windowMs, partitionBy) concurrencyConcurrencyConfigPer-tool concurrency cap (maxConcurrent, optional queue config) timeoutTimeoutConfigPer-tool execution timeout (executeMs) availableWhenEntryAvailabilityRestrict discovery to specific platforms/runtimes/deployments. See Environment Awareness execution{ taskSupport?: 'required' | 'optional' | 'forbidden' }MCP 2025-11-25 task-execution mode for tools/list items authProvidersToolAuthProviderRef[]Required auth providers for this tool (string name or { name, required?, scopes?, alias? }) annotationsToolAnnotationsMCP hints (title, readOnlyHint, destructiveHint, idempotentHint, openWorldHint) examplesToolExample[]Usage examples (description, input, optional output) uiToolUIConfigUI widget configuration (template, csp, sanitization options) hideFromDiscoverybooleanDeprecated alias for visibility: 'hidden'
Output Types
// Object output
@ Tool ({
name : ' create_user ' ,
inputSchema : { name : z . string (), email : z . string (). email () },
outputSchema : z . object ({
id : z . string (),
name : z . string (),
email : z . string (),
}),
})
// Primitive outputs
@ Tool ({
name : ' calculate ' ,
inputSchema : { expression : z . string () },
outputSchema : ' number ' , // Returns a number
})
// MCP content types
@ Tool ({
name : ' generate_image ' ,
inputSchema : { prompt : z . string () },
outputSchema : ' image ' , // Returns base64 image
})
@ Tool ({
name : ' text_to_speech ' ,
inputSchema : { text : z . string () },
outputSchema : ' audio ' , // Returns base64 audio
})
@ Tool ({
name : ' fetch_document ' ,
inputSchema : { uri : z . string () },
outputSchema : ' resource ' , // Returns MCP resource
})
Authorization
@ Tool ({
name : ' sensitive_operation ' ,
inputSchema : { data : z . string () },
authProviders : [
{ name : ' github ' , scopes : [ ' repo ' , ' user ' ] },
],
})
class SensitiveTool extends ToolContext {
async execute ( input ) {
// Access is validated before execute() is called
const token = this . context . authInfo ?. token ;
return await callApi ( token , input . data );
}
}
Annotations
@ Tool ({
name : ' delete_file ' ,
inputSchema : { path : z . string () },
annotations : {
readOnlyHint : false ,
destructiveHint : true ,
idempotentHint : false ,
openWorldHint : false ,
},
})
Examples
@ Tool ({
name : ' search_users ' ,
inputSchema : { query : z . string (), limit : z . number (). optional () },
examples : [
{
description : ' Search for users named "john" ' ,
input : { query : ' john ' , limit : 10 },
output : { users : [{ id : ' 1 ' , name : ' John Doe ' }], total : 1 },
},
],
})
UI Configuration
The ui.template field accepts a builder function, an HTML/MDX string, a React component, or a FileSource (for client-side transpilation):
@ Tool ({
name : ' user_profile ' ,
inputSchema : { userId : z . string () },
ui : {
template : ( ctx ) => ` <div>User ${ ctx . input . userId } </div> ` ,
},
})
See the Tool UI guide for the full ToolUIConfig shape (CSP, sanitization, helpers, etc.).
Function-Based Alternative
For simpler tools, use the tool() function:
import { tool } from ' @frontmcp/sdk ' ;
import { z } from ' @frontmcp/sdk ' ;
const getWeather = tool ({
name : ' get_weather ' ,
description : ' Get current weather ' ,
inputSchema : { city : z . string () },
})(( input , ctx ) => {
// ctx provides access to context methods
const config = ctx . get ( ConfigToken );
return { temperature : 72 , city : input . city };
});
Context Methods
The ToolContext base class provides:
Dependency Injection
async execute ( input ) {
const service = this . get ( ServiceToken ); // Required dependency
const optional = this . tryGet ( OptionalToken ); // Optional dependency
}
Notifications
async execute ( input ) {
// Log message (MCP 2025-11-25 spec)
await this . notify ( ' Processing started ' , ' info ' );
// Progress notification
await this . progress ( 50 , 100 , ' Halfway done... ' );
}
async execute ( input ) {
const result = await this . elicit (
' Please confirm this action ' ,
z . object ({ confirmed : z . boolean () }),
{ mode : ' form ' , ttl : 300000 }
);
if ( result . status === ' accept ' && result . content . confirmed ) {
// Proceed with action
}
}
async execute ( input ) {
// Detect AI platform
if ( this . platform === ' claude ' ) {
// Claude-specific formatting
}
// Get client info
const client = this . clientInfo ; // { name: 'claude', version: '1.0' }
}
Authentication
async execute ( input ) {
const auth = this . context . authInfo ;
const token = auth ?. token ;
const user = auth ?. user ;
}
HTTP Requests
async execute ( input ) {
// Context-aware fetch with auto-injected headers
const response = await this . fetch ( ' https://api.example.com/data ' , {
method : ' POST ' ,
body : JSON . stringify ( input ),
});
}
Error Handling
async execute ( input ) {
if (! input . valid ) {
this . fail ( new Error ( ' Invalid input ' ));
}
// Early return with output
if ( cached ) {
this . respond ( cached ); // Ends execution
}
}
Type Inference
FrontMCP provides helper types for extracting input/output types:
import { ToolInputOf , ToolOutputOf } from ' @frontmcp/sdk ' ;
const metadata = {
name : ' my_tool ' ,
inputSchema : { x : z . number (), y : z . number () },
outputSchema : z . object ({ result : z . number () }),
} as const ;
type Input = ToolInputOf < typeof metadata >; // { x: number; y: number }
type Output = ToolOutputOf < typeof metadata >; // { result: number }
Full Example
import { Tool , ToolContext , App , FrontMcp } from ' @frontmcp/sdk ' ;
import { z } from ' @frontmcp/sdk ' ;
const inputSchema = {
operation : z . enum ([ ' add ' , ' subtract ' , ' multiply ' , ' divide ' ]),
a : z . number (),
b : z . number (),
};
const outputSchema = z . object ({
result : z . number (),
operation : z . string (),
});
@ Tool ({
name : ' calculate ' ,
description : ' Perform arithmetic operations ' ,
inputSchema ,
outputSchema ,
annotations : {
readOnlyHint : true ,
idempotentHint : true ,
},
examples : [
{
description : ' Add two numbers ' ,
input : { operation : ' add ' , a : 2 , b : 3 },
output : { result : 5 , operation : ' add ' },
},
],
})
class CalculateTool extends ToolContext {
async execute ( input ) {
await this . notify ( ` Calculating ${ input . operation } ( ${ input . a } , ${ input . b } ) ` , ' debug ' );
let result : number ;
switch ( input . operation ) {
case ' add ' : result = input . a + input . b ; break ;
case ' subtract ' : result = input . a - input . b ; break ;
case ' multiply ' : result = input . a * input . b ; break ;
case ' divide ' :
if ( input . b === 0 ) this . fail ( new Error ( ' Division by zero ' ));
result = input . a / input . b ;
break ;
}
return { result , operation : input . operation };
}
}
@ App ({ name : ' calculator ' , tools : [ CalculateTool ] })
class CalculatorApp {}
@ FrontMcp ({
info : { name : ' Calculator ' , version : ' 1.0.0 ' },
apps : [ CalculatorApp ],
})
export default class CalculatorServer {}
ToolContext Context class details
ToolRegistry Tool registry API
Tool Errors Tool-related errors
@Resource Define resources