Class Definition
export class AgentContext <
InSchema extends ToolInputType = ToolInputType ,
OutSchema extends ToolOutputType = ToolOutputType ,
In = AgentInputOf <{ inputSchema : InSchema }>,
Out = AgentOutputOf <{ outputSchema : OutSchema }>,
> extends ExecutionContextBase < Out >
Unlike other context classes, AgentContext is not abstract and provides a default execute() implementation that runs the agent loop.
Type Parameters
Parameter Description InSchemaInput schema type OutSchemaOutput schema type InInferred input type OutInferred output type
Properties
Property Type Description metadataAgentMetadataAgent metadata inputInAgent input outputOut | undefinedAgent output llmAdapterAgentLlmAdapterLLM provider adapter systemInstructionsstringSystem prompt toolDefinitionsAgentToolDefinition[]Available tools agentNamestringAgent name agentIdstringAgent ID platformAIPlatformTypeDetected AI platform clientInfoClientInfo | undefinedClient information
Default Behavior
By default, agents run an automatic execution loop:
@ Agent ({
name : ' my-agent ' ,
llm : { adapter : ' openai ' , model : ' gpt-4 ' },
tools : [ MyTool ],
})
class MyAgent extends AgentContext {
// No execute() override needed - uses default loop
}
The default loop:
Builds user message from input
Sends to LLM with available tools
If LLM requests tool call, executes tool and sends result back
Repeats until LLM returns final response
Parses and returns output
Methods
Execution
Main execution method. Override for custom behavior.
async execute ( input : In ) : Promise < Out >
Default implementation calls runAgentLoop().
Run the default agent execution loop.
protected runAgentLoop ( input : In ) : Promise < Out >
async execute ( input ) {
// Pre-processing
await this . notify ( ' Starting agent... ' , ' info ' );
// Run default loop
const result = await this . runAgentLoop ( input );
// Post-processing
return { ... result , processed : true };
}
Message Building (Overridable)
Convert input to LLM message.
protected buildUserMessage ( input : In ) : string
protected buildUserMessage ( input ) {
// Custom message formatting
return ` Task: ${ input . task } \n Context: ${ JSON . stringify ( input . context ) } ` ;
}
parseAgentResponse(content)
Parse LLM response to output type.
protected parseAgentResponse ( content : string | null ) : Out
protected parseAgentResponse ( content ) {
// Custom parsing
return JSON . parse ( content || ' {} ' );
}
LLM Methods
Generate LLM completion.
protected completion (
prompt : AgentPrompt ,
tools ?: AgentToolDefinition [],
options ?: AgentCompletionOptions
) : Promise < AgentCompletion >
const response = await this . completion ({
systemPrompt : ' You are a helpful assistant. ' ,
messages : [{ role : ' user ' , content : ' Hello! ' }],
});
Stream LLM completion.
protected streamCompletion (
prompt : AgentPrompt ,
tools ?: AgentToolDefinition []
) : AsyncGenerator < AgentCompletionChunk >
for await ( const chunk of this . streamCompletion ( prompt )) {
process . stdout . write ( chunk . content || '' );
}
Execute a tool by name.
protected executeTool (
name : string ,
args : Record < string , unknown >
) : Promise < unknown >
protected async executeTool ( name , args ) {
this . logger . info ( ` Executing: ${ name } ` , { args });
return super . executeTool ( name , args );
}
Invoke another agent.
protected invokeAgent (
agentId : string ,
input : unknown
) : Promise < unknown >
const result = await this . invokeAgent ( ' sub-agent ' , { task : ' subtask ' });
Notifications
notify(message, level?)
Send log message notification.
protected notify (
message : string | Record < string , unknown >,
level ?: ' debug ' | ' info ' | ' warning ' | ' error '
) : Promise < boolean >
progress(progress, total?, message?)
Send progress notification.
protected progress (
progress : number ,
total ?: number ,
message ?: string
) : Promise < boolean >
Elicitation
elicit<S>(message, requestedSchema, options?)
Request interactive user input.
protected elicit < S extends ZodType >(
message : string ,
requestedSchema : S ,
options ?: ElicitOptions
) : Promise < ElicitResult < z . infer < S >>>
Custom Agent Example
import { Agent , AgentContext , Tool , ToolContext } from ' @frontmcp/sdk ' ;
import { z } from ' zod ' ;
@ Tool ({
name : ' search ' ,
inputSchema : { query : z . string () },
})
class SearchTool extends ToolContext {
async execute ( input ) {
return { results : [ ` Result for: ${ input . query } ` ] };
}
}
@ Agent ({
name : ' research-agent ' ,
description : ' Researches topics using search ' ,
systemInstructions : ` You are a research assistant.
Use the search tool to find information.
Synthesize findings into a comprehensive report. ` ,
inputSchema : { topic : z . string (), depth : z . enum ([ ' brief ' , ' detailed ' ]) },
outputSchema : z . object ({
summary : z . string (),
sources : z . array ( z . string ()),
}),
llm : {
adapter : ' openai ' ,
model : ' gpt-4-turbo ' ,
apiKey : { env : ' OPENAI_API_KEY ' },
temperature : 0.7 ,
},
tools : [ SearchTool ],
})
class ResearchAgent extends AgentContext {
// Override to add custom logic
async execute ( input ) {
await this . notify ( ` Researching: ${ input . topic } ` , ' info ' );
await this . progress ( 0 , 100 , ' Starting research... ' );
// Run the default agent loop
const result = await this . runAgentLoop ( input );
await this . progress ( 100 , 100 , ' Research complete ' );
return result ;
}
// Override message building
protected buildUserMessage ( input ) {
return ` Research the topic " ${ input . topic } " with ${ input . depth } depth.
Provide a comprehensive summary with sources. ` ;
}
// Override tool execution for logging
protected async executeTool ( name , args ) {
this . logger . info ( ` Agent using tool: ${ name } ` , { args });
await this . notify ( ` Using tool: ${ name } ` , ' debug ' );
return super . executeTool ( name , args );
}
}
Multi-Agent Orchestration
@ Agent ({
name : ' orchestrator ' ,
description : ' Coordinates multiple specialized agents ' ,
llm : { adapter : ' openai ' , model : ' gpt-4 ' },
systemInstructions : ` You orchestrate tasks across specialized agents:
- research-agent: For information gathering
- writer-agent: For content creation
- reviewer-agent: For quality checking
Delegate tasks appropriately and synthesize results. ` ,
})
class OrchestratorAgent extends AgentContext {
async execute ( input ) {
await this . notify ( ' Orchestrator starting... ' , ' info ' );
// Delegate to research agent
const research = await this . invokeAgent ( ' research-agent ' , {
topic : input . topic ,
depth : ' detailed ' ,
});
// Delegate to writer agent
const draft = await this . invokeAgent ( ' writer-agent ' , {
research ,
style : input . style ,
});
// Delegate to reviewer agent
const reviewed = await this . invokeAgent ( ' reviewer-agent ' , {
content : draft ,
});
return reviewed ;
}
}
Full Example
import { Agent , AgentContext , Tool , ToolContext , App , FrontMcp } from ' @frontmcp/sdk ' ;
import { z } from ' zod ' ;
// Tools
@ Tool ({
name : ' calculate ' ,
inputSchema : { expression : z . string () },
})
class CalculateTool extends ToolContext {
async execute ( input ) {
// Safe eval for simple expressions
const result = Function ( ` return ${ input . expression } ` )();
return { result };
}
}
@ Tool ({
name : ' store_result ' ,
inputSchema : { key : z . string (), value : z . any () },
})
class StoreResultTool extends ToolContext {
async execute ( input ) {
await this . remember . set ( input . key , JSON . stringify ( input . value ));
return { stored : true };
}
}
// Agent
@ Agent ({
name : ' math-assistant ' ,
description : ' Helps with mathematical calculations ' ,
systemInstructions : ` You are a math assistant.
- Use the calculate tool for computations
- Use store_result to save intermediate results
- Show your work step by step
- Verify your answers ` ,
inputSchema : {
problem : z . string (). describe ( ' Math problem to solve ' ),
showWork : z . boolean (). default ( true ),
},
outputSchema : z . object ({
answer : z . union ([ z . number (), z . string ()]),
steps : z . array ( z . string ()). optional (),
confidence : z . enum ([ ' high ' , ' medium ' , ' low ' ]),
}),
llm : {
adapter : ' openai ' ,
model : ' gpt-4-turbo ' ,
apiKey : { env : ' OPENAI_API_KEY ' },
temperature : 0.2 , // Lower for math accuracy
},
tools : [ CalculateTool , StoreResultTool ],
tags : [ ' math ' , ' calculator ' ],
})
class MathAssistantAgent extends AgentContext {
async execute ( input ) {
await this . notify ( ` Solving: ${ input . problem } ` , ' info ' );
try {
return await this . runAgentLoop ( input );
} catch ( error ) {
this . logger . error ( ' Agent failed ' , { error });
// Return graceful error response
return {
answer : ' Unable to solve ' ,
confidence : ' low ' ,
steps : [ ` Error: ${ error . message } ` ],
};
}
}
}
@ App ({
name : ' math ' ,
agents : [ MathAssistantAgent ],
tools : [ CalculateTool , StoreResultTool ],
})
class MathApp {}
@ FrontMcp ({
info : { name : ' Math Assistant ' , version : ' 1.0.0 ' },
apps : [ MathApp ],
})
export default class MathServer {}
AgentRegistry Agent registry