Configuration options
Every MentorOptions property with its type, default and effect, grouped by area, plus the options of the WebAssembly client and the YAML loader.
On this page
MentorOptions holds every server-side setting of MentorAgent. You set it once, in the delegate you pass to AddMentorAgent. Each option below has its type, its default and its effect; a required option has no default.
Some options mention the coordinator, the main agent that answers the user, and its specialists: see The three agent levels.
builder.Services.AddScoped<CaseService>();
builder.Services.AddMentorAgent(options =>
{
// Required: without them the options fail validation
options.AppName = "Cases";
options.ScanAssemblies = [typeof(CaseService).Assembly];
options.ChatClient = chatClient; // or options.Agent, never both
// Everything else has a default: set only what you change
options.AppDescription = "Support case management for the service desk";
options.RateLimitPerUser = 20;
});Where the options live
Section titled “Where the options live”| Class | Package | Where you set it |
|---|---|---|
MentorOptions | Novior.MentorAgent | AddMentorAgent(options => …) |
MentorMcpServer, MentorHostedMcpServer, MentorRemoteAgent, AgentCardInfo | Novior.MentorAgent | The McpServers, HostedMcpServers, RemoteAgents and AgentCard options |
ModelPrice | Novior.MentorAgent.Abstractions | The values of ModelPricing |
MentorAgentBlazorOptions | Novior.MentorAgent.Blazor | AddMentorAgentBlazor(options => …), in a WebAssembly client |
AgentDisplayInfo | Novior.MentorAgent.Abstractions | The values of MentorAgentBlazorOptions.RemoteAgentDisplays |
MentorDeclarativeOptions | Novior.MentorAgent.Declarative | AddMentorAgentDeclarative(o => …) |
Novior.MentorAgent.Server has no options class. The SignalR hub, the Server-Sent Events (SSE) endpoint, the MCP server and the A2A agent all read MentorOptions. The paths of the hub and of the SSE endpoint are parameters of MapMentorAgentServer.
Novior.MentorAgent.Server also registers the MCP server and the A2A agent. AddMentorAgentServer() does it when their options are on. A host without the hub, such as a Blazor Server app, calls AddMentorAgentMcp() or AddMentorAgentA2A() after AddMentorAgent().
The widget reads a copy of its settings as MentorWidgetOptions, which MentorAgent fills from MentorOptions or from MentorAgentBlazorOptions. Set them there, not on MentorWidgetOptions.
Validation
Section titled “Validation”MentorAgent checks the options when the host starts, not when you call AddMentorAgent. In an ASP.NET Core app or in a worker, an invalid configuration stops the start with the reason, before the first request. An app without such a host, such as a .NET MAUI app, has no start to check: the error appears the first time MentorAgent reads the options. The check throws InvalidOperationException when:
AppNameis empty or blank;ScanAssembliesis empty;- neither
ChatClientnorAgentis set, or both are; - both
ChatHistoryProviderandChatHistoryProviderFactoryare set.
When MentorAgent reads the options
Section titled “When MentorAgent reads the options”- The callback runs twice.
AddMentorAgentruns your callback once on a copy of the options, to decide what to register, and once more when it builds the real options. Keep the callback free of side effects that must happen once. - Some options come from the copy.
EnableObservability,ObservabilitySourceName,McpServerEnabledandA2AServerEnabledare read at registration, and so isAppNamefor the MCP server. Set them in the callback: aConfigure<MentorOptions>registered afterAddMentorAgentdoes not reach them. MentorAgent reads every other option from the real options. - A callback that throws on the copy leaves those options at their defaults. A warning with the exception is logged when the host starts.
AppName
Section titled “AppName”string · Required
The name of your application. It goes into the system prompt, into the topic that the safety check and the off-topic check judge messages against, and into the A2A agent card.
AppDescription
Section titled “AppDescription”string · Default: ""
One or two sentences on what your application does. The model reads it as context. The input safety check also uses it to judge messages: without a description, the check must guess what your application is about.
Language
Section titled “Language”MentorLanguage · Default: English
The language of the replies and of the widget's texts: English, Italian, French, German, Spanish, Portuguese, Dutch, Polish, Japanese or Chinese. The confirmation box is built from the action's Description and its parameter names, which are not translated: write them in your users' language.
MentorshipLevel
Section titled “MentorshipLevel”MentorshipLevel · Default: Standard
How much the agent explains and suggests:
Minimal: it carries out requests without explanations or suggestions. For expert users.Standard: balanced answers, with suggestions when they are relevant.Proactive: it explains what it did and why, suggests next steps and warns of risks. It may offer a next step only when a tool of the current request, a page, a skill, a specialist or a team can carry it out. The model does not always follow this rule, so it can still suggest an action your application does not have: see Known issues.
ChatClient
Section titled “ChatClient”IChatClient? · Default: null
The model, as a Microsoft.Extensions.AI IChatClient: Azure OpenAI, OpenAI, Ollama or any provider that has one. This is the recommended path: specialists, teams, remote agents, hosted tools, tool filtering and routing need it. Set this or Agent, not both.
MentorAgent brings no SDK of a model provider. Add the package that your provider needs, for example Azure.AI.OpenAI or Microsoft.Extensions.AI.OpenAI. See Choose a path in Model providers.
AIAgent? · Default: null
A ready-made Agent Framework AIAgent. Use it for providers that do not expose an IChatClient, such as Foundry's AIProjectClient. For Foundry, add its package yourself. Features that need ChatClient are not available. Set this or ChatClient, not both. See Foundry agents (Path B).
EmbeddingGenerator
Section titled “EmbeddingGenerator”IEmbeddingGenerator<string, Embedding<float>>? · Default: null
An embedding model, which turns a text into a list of numbers that represents its meaning, so that MentorAgent can compare texts. EnableToolFiltering, MemoryRelevanceFiltering and the Semantic RoutingStrategy need it. It does not turn them on: each has its own option. If you turn one on without an embedding model, MentorAgent logs a warning and the feature stays off.
ScanAssemblies
Section titled “ScanAssemblies”Assembly[] · Required
The assemblies MentorAgent scans for actions, agents, teams, pages and skills. Usually [typeof(Program).Assembly]. See Attributes.
Widget
Section titled “Widget”MentorTheme · Default: Default
The widget's theme: Default, Dark, Minimal or Custom. Custom injects no theme overrides and renders like Default: your stylesheet decides what changes.
Position
Section titled “Position”ChatPosition · Default: BottomRight
Where the widget sits: BottomRight, BottomLeft, TopRight, TopLeft, or a full-height side panel with SideRight and SideLeft.
PrimaryColor
Section titled “PrimaryColor”string? · Default: null
An accent color in hex, for example #2563EB. null keeps the theme's color.
BotName
Section titled “BotName”string · Default: "Mentor AI"
The name shown in the widget header.
AvatarUrl
Section titled “AvatarUrl”string? · Default: null
The URL of the avatar shown in the widget. null uses the built-in one.
WelcomeMessage
Section titled “WelcomeMessage”string? · Default: null
The message shown while the chat is empty. The widget renders it as HTML, so never build it from user input. null uses the built-in message.
InputPlaceholder
Section titled “InputPlaceholder”string? · Default: null
The placeholder of the input box. With null, the widget uses the text in the language of Language: "Write a message..." in English.
EnableSuggestions
Section titled “EnableSuggestions”bool · Default: true
Shows starter suggestion chips in the widget's welcome panel. No hub event or SSE frame carries suggestions, so it has no effect on a React, Angular or Vue client, or on any other client of the hub.
EnableActionFeedback
Section titled “EnableActionFeedback”bool · Default: true
Shows a feedback line while one of your tools runs; over the hub it sends ActionExecuting and ActionCompleted. Hosted tools have their own switch, ShowHostedToolActivity.
EnableOnboardingTour
Section titled “EnableOnboardingTour”bool · Default: false
Shows a short guided tour the first time a user opens the widget. MentorAgent generates it from your [MentorPage] pages and the agent's tools. Novior.MentorAgent.Server answers GET /mentor/tour even when this option is false: a client of the server decides for itself whether to show the tour.
EnableGenerativeCards
Section titled “EnableGenerativeCards”bool · Default: true
Renders a MentorCard returned by a tool as a card. With false the data reaches the model as text, and the model describes it.
EnableRichResponses
Section titled “EnableRichResponses”bool · Default: true
Asks the coordinator to format answers as Markdown, with tables and lists. The widget always renders Markdown safely. With false, the coordinator is asked for short answers in plain text.
EnableVoiceInput
Section titled “EnableVoiceInput”bool · Default: false
Shows a microphone button that uses the browser's Speech Recognition API. The browser does the recognition: in Chrome, for example, it sends the audio to its vendor's service, and only the transcript reaches MentorAgent. Another client does its own capture and sends the transcript as an ordinary message.
EnableVoiceOutput
Section titled “EnableVoiceOutput”bool · Default: false
Reads replies aloud with the browser's Speech Synthesis API. Synthesis always happens on the client.
VoiceStreaming
Section titled “VoiceStreaming”bool · Default: true
Speaks each sentence as it streams, instead of reading the finished answer back.
VoiceBargeIn
Section titled “VoiceBargeIn”bool · Default: true
Stops the spoken answer when the user acts: presses the microphone, sends a message, presses Stop or starts a new conversation.
VoiceHandsFree
Section titled “VoiceHandsFree”bool · Default: false
Lets the user talk without touching the widget: the message is sent when the user stops speaking, and the microphone opens again when the spoken answer ends. Ignored unless both EnableVoiceInput and EnableVoiceOutput are on.
VoiceRate
Section titled “VoiceRate”double · Default: 1.0
The speech rate, passed to SpeechSynthesisUtterance.rate. The useful range is about 0.5 to 2.0.
Image input
Section titled “Image input”EnableImageInput
Section titled “EnableImageInput”bool · Default: false
Lets users send images with a message. In the widget, they can upload, paste or drag and drop an image, or give its URL. In Novior.MentorAgent.Server, images arrive as attachments of SendMessage and POST /mentor/chat. The chat model must support images.
MaxImageBytes
Section titled “MaxImageBytes”int · Default: 4194304
The maximum size of one image, 4 MB. Checked on the server.
MaxImagesPerMessage
Section titled “MaxImagesPerMessage”int · Default: 4
The maximum number of images in one message. Checked on the server.
AllowedImageTypes
Section titled “AllowedImageTypes”IReadOnlyList<string> · Default: ["image/png", "image/jpeg", "image/gif", "image/webp"]
The accepted MIME types, as an allow-list. Anything else is dropped with a warning.
Confirmation and approval
Section titled “Confirmation and approval”Before an action runs, MentorAgent can ask the user to confirm it, in the confirmation box. Agent Framework calls this step an approval: on this page, confirmation and approval mean the same thing. See Roles, confirmation and governance.
RequireConfirmation
Section titled “RequireConfirmation”bool · Default: true
Turns confirmation on or off for the whole application. With true, the default, a tool asks for confirmation in three cases:
- you declare
RequiresConfirmation = trueon an action, seeRequiresConfirmation; - the
RequiresApprovalpredicate matches the tool, or you setMentorMcpServer.RequiresConfirmationon a server ofMcpServers; - the tool is a
[MentorAction]that changes data and declares nothing: seeRequireConfirmationForWrites.
Do not confuse this option, RequireConfirmation, with the attribute parameter RequiresConfirmation.
With false:
- no action or tool asks for confirmation;
RequiredRolesstill refuses a user without the role;- the only approvals that still appear are those for the MCP servers that the model provider calls directly (
HostedMcpServers); - tool filtering still reads what you declared: see
EnableToolFiltering; RequireActionForChangeRequestsrequires no action, because no action shows a confirmation box.
See Roles, confirmation and governance.
RequireConfirmationForWrites
Section titled “RequireConfirmationForWrites”bool · Default: true
Makes a [MentorAction] ask for confirmation when it declares neither ReadOnly = true nor RequiresConfirmation. MentorAgent treats such an action as one that changes data. To keep an action out, declare it:
ReadOnly = trueon an action that only reads, orIsReadOnlyActionby tool name;RequiresConfirmation = falseon a write that must run without asking.
public class CaseReview(ICaseReviewStore store)
{
// Declares nothing: MentorAgent treats it as a write, and it asks for confirmation
[MentorAction(Description = "Reopens a closed support case")]
public Task ReopenCaseAsync(string caseNumber, string reason)
=> store.ReopenAsync(caseNumber, reason);
// Only reads: it never asks
[MentorAction(Description = "Lists the notes of a support case", ReadOnly = true)]
public Task<string> ListCaseNotesAsync(string caseNumber)
=> store.ListNotesAsync(caseNumber);
// A write that is easy to undo and must run without asking
[MentorAction(Description = "Flags a support case for review", RequiresConfirmation = false)]
public Task FlagCaseAsync(string caseNumber)
=> store.FlagAsync(caseNumber);
}An action that asks is withheld from the MCP server and from the A2A agent card, like every action that asks: nobody there can answer. Tool filtering does not send it when a message matches nothing.
The option covers [MentorAction] methods only. A method with only [Description] asks for nothing and stays on /mcp: mark it [MentorAction] to have the default.
The first time MentorAgent reads your actions, a warning lists the writes that run without confirmation, in two lists: the [MentorAction] methods that opted out, and the methods with only [Description] that are not declared read-only. MentorAgent reads your actions:
- at startup, when the host maps the A2A agent or turns on
WarmUpAtStartup; - at the first MCP request or the first request for the tour;
- otherwise, at the first message.
With false, an action asks only when it declares RequiresConfirmation = true. RequireConfirmation set to false turns off every confirmation of your actions, this default included.
HitlMode
Section titled “HitlMode”MentorHitlMode · Default: Blocking
How the server handles a confirmation. HITL stands for human in the loop, and Agent Framework calls a confirmation an approval.
Blocking: MentorAgent's own flow. The run waits for the user's answer.Native: Agent Framework's approval protocol, for interoperability. After the answer, the turn resumes in a new run.
The confirmation box, the client protocol and the model calls are the same in both modes. When the user declines, in both modes the model is told that the user declined, that nothing was checked or changed, and that it must not give another reason.
With Native, Stop pressed while a confirmation box waits does not break the conversation: the next message answers the open request as not run. A snapshot saved after that Stop and restored later still carries the open request: see Known issues. See Blocking and Native modes.
RequiresApproval
Section titled “RequiresApproval”Func<string, bool>? · Default: null
A predicate on the tool name: return true to ask the user to confirm before that tool runs. It works in addition to RequiresConfirmation. Use it for tools that have no attribute you can set, such as MCP tools and skills. The name is the tool name, not the method name: CloseCaseAsync becomes close_case.
IsReadOnlyAction
Section titled “IsReadOnlyAction”Func<string, bool>? · Default: null
A predicate on the tool name: return true to declare that the action only reads. It does the same as ReadOnly on [MentorAction], for methods that have only [Description], or to declare many actions in one place. MentorAgent takes your word for it and does not check it.
- The MCP server publishes the action with
readOnlyHint. RequireLookupForRecordQuestionscan require the agent to call it.- A tool that needs confirmation is never read-only, whatever the predicate returns.
- It does not apply to the tools of the MCP servers you connect to: their own
readOnlyHintdecides.
The name is the tool name, not the method name: GetCaseStatusAsync becomes get_case_status.
AutoApprovalRules
Section titled “AutoApprovalRules”IList<Func<ToolAutoApprovalRuleContext, ValueTask<bool>>> · Default: empty
Works only with HitlMode = Native. MentorAgent evaluates the rules in order. The first rule that returns true approves the call, and no confirmation box appears. Setting a rule, or MaxAutoApprovalIterations, also turns on "don't ask again": after the user approves a call, matching calls stop asking for the rest of the session. A rule skips the question, not the role check: RequiredRoles still applies. Rules do not cover the tools of specialists and teams. A call that RequireActionForChangeRequests requires is never approved by a rule: the confirmation box always appears.
MaxAutoApprovalIterations
Section titled “MaxAutoApprovalIterations”int? · Default: null
Native mode only. A cap on how many times one turn may run again because its approvals were granted by AutoApprovalRules. Each run is a billable model call. null uses Agent Framework's default.
Security and limits
Section titled “Security and limits”EnableSafetyCheck
Section titled “EnableSafetyCheck”bool · Default: false
Before each turn, asks a model whether the message is a prompt injection, a jailbreak or an attempt to extract the system prompt or credentials. It adds one call per message, on ClassifierChatClient.
SafetyCheckTimeout
Section titled “SafetyCheckTimeout”TimeSpan · Default: 00:00:15
How long the input and output checks may take before they count as failed. TimeSpan.Zero or a negative value means no limit, and Stop still cancels a check. Raise it for a slow local model.
SafetyCheckFailure
Section titled “SafetyCheckFailure”MentorSafetyCheckFailure · Default: Allow
What happens when a safety check gives no verdict, after a timeout or an error. Allow lets the message or the reply through, and logs a warning. Block refuses the message, or withholds the reply. A check that finds the message or the reply unsafe blocks it with both values.
RefuseOutOfScope
Section titled “RefuseOutOfScope”bool · Default: false
Politely refuses a message that plainly has nothing to do with your application, without calling the coordinator. When the classifier is unsure, the message is answered: a name it does not recognize may be one of your records, and greetings, follow-up questions and questions about the agent are answered too.
MentorAgent judges the message against HostedToolDomainScope or, when that is not set, against your app's name, description, and the names and descriptions of your pages. With EnableSafetyCheck on, one call answers both questions, with a longer prompt. Without it, the option adds one small model call per turn. When HostedToolDomainCheck is on, a turn that is about to declare a hosted tool still asks that check its own, stricter question. Each refusal counts in GuardrailBlockCount and in the mentoragent.guardrail_blocks metric.
WarmUpAtStartup
Section titled “WarmUpAtStartup”bool · Default: false
Builds one coordinator when the application starts, so the first user does not wait for the shared work: tool embeddings, shared MCP sessions, remote agent cards. It runs once the host has started, after a web host starts listening. A failure of the warm-up itself never stops the application, but an invalid configuration does. It needs a generic host, such as ASP.NET Core or a worker: a .NET MAUI app runs no hosted service, so there the option does nothing.
MaxMessageLength
Section titled “MaxMessageLength”int · Default: 4000
The maximum length of a message, in characters. A longer message is refused before the model is called. 0 means no limit.
RateLimitPerUser
Section titled “RateLimitPerUser”int · Default: 0
The maximum number of messages per user in each RateLimitWindowSecs window. 0 turns the limit off. MentorAgent counts a signed-in user by the same key as memory: the NameIdentifier claim, else sub, oid or the name. It counts an anonymous user by AnonymousIdentity. With the default, PerSession, a page reload starts a new count. So only signed-in users get a real limit per user.
The tool calls of the MCP server are limited too, with the same limit and window, but in an allowance of their own, separate from the chat messages of the same user. MentorAgent counts the caller by its NameIdentifier, sub or oid claim, or else by its name. A caller with none of them is counted by remote address when the host registers IHttpContextAccessor, as AddMentorAgentServer() and AddMentorAgentA2A() do. Otherwise all such callers share one allowance, and one busy client can use it up for the others. A call over the limit gets an isError result.
RateLimitWindowSecs
Section titled “RateLimitWindowSecs”int · Default: 60
The length of the rate-limit window, in seconds.
IncludeWorkflowExceptionDetails
Section titled “IncludeWorkflowExceptionDetails”bool · Default: false
Puts the exception message of a failing specialist or team into the reply the user reads. Development only.
Middleware and guardrails
Section titled “Middleware and guardrails”These options add checks on messages and replies, your own or built in, and let you change tool results, error messages and the pipeline around ChatClient. A guardrail is a check you write: it returns true when the text is safe.
InputGuardrail
Section titled “InputGuardrail”Func<string, CancellationToken, Task<bool>>? · Default: null
Your own check on each incoming message; return true when it is safe. When set, it runs on every message and replaces the built-in check of EnableSafetyCheck.
OutputGuardrail
Section titled “OutputGuardrail”Func<string, CancellationToken, Task<bool>>? · Default: null
Your own check on the completed reply; return true when it is safe. While it is set, each reply is held back and shown after the check, without live streaming.
EnableOutputSafetyCheck
Section titled “EnableOutputSafetyCheck”bool · Default: false
The built-in check on the reply: it blocks a reply that leaks instructions or secrets, discloses someone's personal data or contains harmful content. The reply is shown after the check. It runs on ClassifierChatClient, or on ChatClient when that is not set, and a custom OutputGuardrail takes precedence.
OnToolResult
Section titled “OnToolResult”Func<string, object?, object?>? · Default: null
Transforms or redacts a tool result before it returns to the model. It receives the tool name and the result. It also runs on the result of each call to the MCP server, before the caller sees it. If the hook throws, an MCP caller gets an isError result and not the data. In the chat, the model is told that the action ran and that its result was withheld, and not to run it again.
OnException
Section titled “OnException”Func<Exception, string?>? · Default: null
Maps an exception to the message the user sees. Return null to keep the built-in message.
When a tool throws, the message goes to the chat and to the model:
- With the hook set, the chat never shows the text of the exception. It shows your message. When the hook returns
nullor an empty string, or throws, it shows "The action could not be completed." in the language of the widget. - The model gets your message or, without one, the message of the exception, because it needs a reason to answer. Return a message for any exception whose text must not reach the model.
- Without the hook, the chat and the model both get the message of the exception.
Only an exception of the tool itself counts as a failure. The log has the type of the exception, and the whole exception at Debug level.
ConfigureChatClientPipeline
Section titled “ConfigureChatClientPipeline”Func<ChatClientBuilder, ChatClientBuilder>? · Default: null
Adds your own middleware, such as logging or caching, to the pipeline that MentorAgent builds around ChatClient. Your middleware wraps MentorAgent's own middleware: it is the outermost layer.
Session and history
Section titled “Session and history”These options control the history: the messages of the current conversation, which the model receives again at each turn. By default MentorAgent keeps the history in memory. A history provider can store it elsewhere, for example in a database.
MaxSessionMessages
Section titled “MaxSessionMessages”int · Default: 50
The maximum number of messages that the default in-memory history keeps. Every message counts, tool calls and tool results included. MentorAgent removes whole turns, oldest first, so the model still sees the data that a tool read in the previous turn. 0 or a negative value turns trimming off, with a warning. MentorAgent does not read it when ChatReducer is set, for a history provider you supply, or with UseServiceManagedHistory.
ChatReducer
Section titled “ChatReducer”IChatReducer? · Default: null
Replaces the reducer that keeps the default in-memory history short. A reducer decides which messages the history keeps. With null, MentorAgent uses a MentorChatReducer of MaxSessionMessages messages. It cuts whole turns, oldest first, and keeps every tool call together with its result.
When you set it, MentorAgent uses it as it is and does not read MaxSessionMessages. One instance serves every session, so it must not keep the state of one conversation. To keep only the text of the conversation, set a MessageCountingChatReducer: it is experimental in Microsoft.Extensions.AI (diagnostic MEAI001).
It applies to the default history of ChatClient only. A ChatHistoryProvider or ChatHistoryProviderFactory of yours is used as it is: give it a reducer yourself, for example new MentorChatReducer(50) from the namespace Novior.MentorAgent.Core. With UseServiceManagedHistory, or when you supply a provider, a set ChatReducer has no effect and MentorAgent logs a warning.
ChatHistoryProvider
Section titled “ChatHistoryProvider”ChatHistoryProvider? · Default: null
A persistent history provider. One instance serves every user in the process: use it only in a single-user host, or with a provider that partitions its own storage. With Agent, set the provider on the agent instead.
ChatHistoryProviderFactory
Section titled “ChatHistoryProviderFactory”Func<IServiceProvider, ChatHistoryProvider>? · Default: null
Builds a history provider once per coordinator: per circuit, per hub connection, per app instance. Prefer it whenever the application has more than one user. Setting it together with ChatHistoryProvider fails validation. The provider is kept across new conversations, so it must keep the transcript in the session, not in a field: see Conversation history and memory.
UseServiceManagedHistory
Section titled “UseServiceManagedHistory”bool · Default: false
Set it when the chat client keeps the conversation on the service, as the OpenAI and Azure OpenAI Responses client does. MentorAgent then installs no history provider and no compaction, and MaxSessionMessages, ChatReducer, EnableCompaction and your history provider no longer apply. A session snapshot records how the history is kept, and a host that keeps it the other way refuses the snapshot.
Memory
Section titled “Memory”Memory keeps facts about each user across conversations, such as a name, a role or a preference, and adds them to the prompt.
UseMemoryContext
Section titled “UseMemoryContext”bool · Default: false
Turns on memory across conversations. MentorAgent identifies a signed-in user by the NameIdentifier claim, else by sub, oid or the name of the identity. A key made from sub, oid or the name starts with the claim name (sub:…, name:…), so a name never matches the identifier of another user. It identifies an anonymous user by AnonymousIdentity. A signed-in user with none of these is keyed as an anonymous one. Memories live in RAM unless you register your own IMentorMemoryStore before AddMentorAgent.
AnonymousIdentity
Section titled “AnonymousIdentity”MentorAnonymousIdentity · Default: PerSession
Who an anonymous user is, for memory and for the rate limit. PerSession gives each circuit or connection its own key. Shared gives every anonymous user the same key, anonymous. Use Shared only in a single-user app, such as a .NET MAUI app: on a website, users would share memories and the rate limit. Ignored for a signed-in user.
MemoryContextCount
Section titled “MemoryContextCount”int · Default: 10
How many memories go into the prompt: the most recent, or the most relevant with MemoryRelevanceFiltering.
MemoryRelevanceFiltering
Section titled “MemoryRelevanceFiltering”bool · Default: false
Injects only the memories related to the message, by embedding similarity, plus the identity and preference facts. Needs EmbeddingGenerator; without it the most recent ones are used.
MemoryAutoCapture
Section titled “MemoryAutoCapture”bool · Default: true
With UseMemoryContext on, a small extraction call after each message saves lasting facts about the user. With ChatClient, this call is the only way memories are saved, and the remember tool is removed. With Agent, the remember tool stays, and the extraction runs only when ClassifierChatClient is set. false saves the extra call.
Retrieval-augmented generation (RAG) lets the model answer from your own documents. For each message, before the coordinator answers, MentorAgent searches them and adds the relevant ones to the prompt.
You write the search yourself, as a class that implements IMentorRagSource, and register it in dependency injection. MentorAgent does not wrap an ITextSearch for you: call it from your own source.
| Member | What it does |
|---|---|
SearchAsync(string query, int maxResults, CancellationToken) | Searches with the text of the message. Every source implements it. |
SearchAsync(MentorRagRequest request, CancellationToken) | The method that MentorAgent calls. Its default implementation calls the first one, so implement it only when the search needs more than the text. |
DefaultMinScore | The relevance threshold for the scores of your source. It applies when you do not set RagMinScore. |
Do not make each SearchAsync call the other: the search would never return.
A MentorRagRequest holds:
| Property | Holds |
|---|---|
Query, MaxResults | The message of the user, and RagResultCount. |
RecentMessages | The messages before this one, oldest first: the user's messages and the replies of the last three turns of this conversation, as text. It is empty on the first turn, after a reset and after a restore. Over Server-Sent Events it is always empty, because each request is a conversation of its own. |
User | The caller of the hub, of /mentor/chat or of an A2A request. In a Blazor circuit, the user that the AuthenticationStateProvider of the host reports. It is null when the host has no authentication. An anonymous visitor has an unauthenticated principal. Filter restricted documents on it. |
PageName, PageData | The name of the current page and the data that the page put in context with IMentorPageContext. |
A result is a MentorRagResult: the content, the source URL, the title and the score. It can also carry Metadata, facts about the document such as a date or a version. The model sees them under the title of the document, one key: value per entry, so it can tell the 2025 price list from the 2026 one. They also travel to the client with the citation chips, and the model can repeat them in its reply. Put nothing in them that the user must not see.
public class CaseKnowledgeSource(ICaseKnowledge knowledge) : IMentorRagSource
{
// The scores of this source are cosine similarities, between 0 and 1: say which threshold suits them
public float? DefaultMinScore => 0.6f;
// The method that MentorAgent calls: it sees who is asking
public Task<IReadOnlyList<MentorRagResult>> SearchAsync(MentorRagRequest request, CancellationToken ct = default)
=> FindAsync(request.Query, request.MaxResults, request.User, ct);
// Required by the interface. Share the search through a third method: never call one SearchAsync from the other
public Task<IReadOnlyList<MentorRagResult>> SearchAsync(string query, int maxResults, CancellationToken ct = default)
=> FindAsync(query, maxResults, user: null, ct);
async Task<IReadOnlyList<MentorRagResult>> FindAsync(string text, int max, ClaimsPrincipal? user, CancellationToken ct)
{
// The knowledge base returns only the articles that this user may read
var articles = await knowledge.FindAsync(text, max, user, ct);
return [.. articles.Select(a => new MentorRagResult(a.Text, a.Url, a.Title, a.Score)
{
// Facts the model weighs with the text: it can tell the 2025 price list from the 2026 one
Metadata = new Dictionary<string, string> { ["valid from"] = a.ValidFrom },
})];
}
}UseRag
Section titled “UseRag”bool · Default: false
Searches your knowledge base before each coordinator call and adds the relevant documents to the prompt. Needs a registered IMentorRagSource.
RagResultCount
Section titled “RagResultCount”int · Default: 5
How many documents are retrieved for each message.
RagMinScore
Section titled “RagMinScore”float · Default: 2
The minimum relevance score of a document. The scale depends on your source. With keyword search, 2 means about two matches. With cosine similarity (a score from 0 to 1), use 0.5 to 0.75. 0 turns filtering off.
MentorAgent uses the first of these thresholds that applies:
- this option, when you set it in code or in configuration;
- the
DefaultMinScoreof the source, when it declares one; - the default of this option,
2.
A source with cosine scores should declare a DefaultMinScore. Without one, the default 2 discards every document, and a warning says which threshold discarded them.
RagSystemPromptTemplate
Section titled “RagSystemPromptTemplate”string · Default: "Use the following documents to answer:\n{documents}"
The text that introduces the documents in the prompt; {documents} is replaced with them.
ShowRagSources
Section titled “ShowRagSources”bool · Default: false
Shows citation chips under the agent's replies. The pages of a hosted web search and the documents of a file search use the same chips. The Metadata of a document travels with its chip. Over the hub, the client receives it in the metadata field of RagSourcesReady.
Agent Skills
Section titled “Agent Skills”A skill is a set of instructions, with optional resources, that the model loads only when it needs them. Until then, the prompt carries only the skill's name and description.
EnableSkills
Section titled “EnableSkills”bool · Default: false
Turns on skill discovery and the load_skill and read_skill_resource tools. Skills are declared with [MentorSkill] or as files.
SkillsFolder
Section titled “SkillsFolder”string · Default: "Skills"
The folder of file-based skills, with one sub-folder and one SKILL.md per skill. Relative to the content root, or absolute.
SkillSources
Section titled “SkillSources”IList<AgentSkillsSource> · Default: empty
More skill sources, through Agent Framework's own abstraction: a database, a remote catalog or AgentFileSkillsSource. Your own skills win a name collision.
SkillFilter
Section titled “SkillFilter”Func<AgentSkill, bool>? · Default: null
Keeps or drops a skill that comes from SkillSources. It never applies to the skills MentorAgent discovered itself.
SkillsRefreshInterval
Section titled “SkillsRefreshInterval”TimeSpan? · Default: null
How long a list of skills from SkillSources stays fresh. While it is fresh, every session in the process shares it. The first session that starts after the interval reads the sources again. With null, there is no shared list: every new session reads the sources. Set it for a remote or slow source.
The Model Context Protocol (MCP) lets an AI application use tools from other programs. MentorAgent can be an MCP client: it uses the tools of external MCP servers. It can also be an MCP server: it publishes your actions to MCP clients.
McpServers
Section titled “McpServers”MentorMcpServer[]? · Default: null
External MCP servers your application connects to as a client. Their tools become tools of the coordinator, like your actions. See MentorMcpServer.
McpServerEnabled
Section titled “McpServerEnabled”bool · Default: false
Exposes your actions as an MCP server. The server is in the Novior.MentorAgent.Server package: call AddMentorAgentMcp() after AddMentorAgent (AddMentorAgentServer() does it for you), and app.MapMentorAgentMcp(). MentorAgent reads this option when you call AddMentorAgent, so set it in that callback.
Actions that need confirmation are never published, and that includes a [MentorAction] that asks by default: see RequireConfirmationForWrites and where nobody can answer. An action declared read-only is published with readOnlyHint: some MCP clients skip their own confirmation for such a tool, so declare it only on an action that really only reads. Every tool call passes through OnToolResult and RateLimitPerUser.
The endpoint has no CORS policy, which suits desktop and IDE clients. A client that runs in a browser needs an opt-in. See MCP server.
McpServerPath
Section titled “McpServerPath”string · Default: "/mcp"
The path MapMentorAgentMcp() maps when you pass none. A path passed to the method wins.
McpCallerPrincipal
Section titled “McpCallerPrincipal”Func<ClaimsPrincipal?>? · Default: null
Tells MentorAgent who is calling the MCP server. An action with RequiredRoles is then published to an authenticated caller who has one of its roles. With null, every action with RequiredRoles is withheld. They are also withheld when the resolver returns null or an unauthenticated user, or when it throws.
MentorAgent tests the roles with ClaimsPrincipal.IsInRole. A roles claim works once the identity names it as its RoleClaimType. With JwtBearer and MapInboundClaims = false, set TokenValidationParameters.RoleClaimType = "roles". MentorAgent calls the resolver once for each MCP request and never keeps the answer for another caller, so keep it cheap.
ShowMcpStatus
Section titled “ShowMcpStatus”bool · Default: false
Shows a badge in the widget header with the connection status of McpServers.
The Agent-to-Agent (A2A) protocol lets AI agents call each other. MentorAgent can hand requests to remote A2A agents, and it can answer as an A2A agent itself. An A2A agent describes itself in an agent card, a JSON document at /.well-known/agent-card.json.
RemoteAgents
Section titled “RemoteAgents”MentorRemoteAgent[]? · Default: null
Remote A2A agents the coordinator can hand requests to, like local specialists. They need ChatClient. Any user of your application can reach them: see MentorRemoteAgent.
A2AServerEnabled
Section titled “A2AServerEnabled”bool · Default: false
Exposes your application as an A2A agent. The agent is in the Novior.MentorAgent.Server package: call AddMentorAgentA2A() after AddMentorAgent (AddMentorAgentServer() does it for you), and app.MapMentorAgentA2A(). MentorAgent reads this option when you call AddMentorAgent. See A2A server.
A2AServerPath
Section titled “A2AServerPath”string · Default: "/a2a"
The path of the A2A task handler when you pass none to MapMentorAgentA2A(). The agent card stays at /.well-known/agent-card.json.
A2AServerUrl
Section titled “A2AServerUrl”string? · Default: null
The full public URL of your A2A endpoint, path included. MentorAgent publishes it as it is in the agent card. With null, the card carries only the path: a MentorAgent caller resolves it against the address of the card, and another A2A client may not. Set it whenever other agents call this one.
AgentCard
Section titled “AgentCard”AgentCardInfo? · Default: null
Extra metadata for the agent card; the name and description come from AppName and AppDescription. See AgentCardInfo.
ShowA2AStatus
Section titled “ShowA2AStatus”bool · Default: false
Shows a badge in the widget header that lists the configured remote agents.
Hosted tools
Section titled “Hosted tools”Hosted tools run on the model provider's infrastructure, not in your application: web search, code interpreter, file search, image generation and remote MCP servers. MentorAgent's roles and confirmation do not apply to them: see HostedTools.
HostedTools
Section titled “HostedTools”MentorHostedTools · Default: None
The provider-hosted tools that the model may use, as flags: WebSearch, CodeInterpreter, FileSearch, ImageGeneration, HostedMcp. They run on the provider's infrastructure and need ChatClient. Which ones work depends on the client: the Responses client supports them all, and the Chat Completions client supports at most web search. Roles, confirmation and OnToolResult do not apply to them.
FileSearchVectorStoreIds
Section titled “FileSearchVectorStoreIds”IReadOnlyList<string>? · Default: null
The provider's vector stores that FileSearch searches. Required when FileSearch is on: without an id the tool is skipped and a warning is logged.
FileSearchMaxResults
Section titled “FileSearchMaxResults”int? · Default: null
An upper bound on file-search matches. null lets the provider decide.
HostedImageModel
Section titled “HostedImageModel”string? · Default: null
The model ImageGeneration uses, for example gpt-image-1-mini. On Azure OpenAI it is not enough: the image deployment must also travel in the x-ms-oai-image-generation-deployment request header, which you add where you build the Azure client.
HostedImageSize
Section titled “HostedImageSize”string? · Default: null
The size of generated images as WIDTHxHEIGHT, for example 1024x1024: the setting that controls the cost of image generation. A value that cannot be read is ignored with a warning.
HostedMcpServers
Section titled “HostedMcpServers”IReadOnlyList<MentorHostedMcpServer>? · Default: null
The remote MCP servers the provider connects to for HostedMcp. Required when HostedMcp is on. See MentorHostedMcpServer.
ShowHostedToolActivity
Section titled “ShowHostedToolActivity”bool · Default: true
Shows hosted-tool work while it happens: "Searching the web…", "Running code…", "Generating the image…". Citations also need ShowRagSources.
ShowHostedToolsStatus
Section titled “ShowHostedToolsStatus”bool · Default: false
Shows a badge in the widget header that lists the active hosted tools. A development aid.
FilterHostedTools
Section titled “FilterHostedTools”bool · Default: true
Offers each hosted tool to the model only when the semantic filter finds it relevant to the message. Needs EnableToolFiltering and EmbeddingGenerator; without them nothing is filtered and a warning is logged.
HostedToolFilterMinScore
Section titled “HostedToolFilterMinScore”float? · Default: null
The similarity threshold for hosted tools; null means 0.15. Keep it low: this filter is only a first, rough selection, and HostedToolDomainCheck makes the final decision.
HostedToolDomainCheck
Section titled “HostedToolDomainCheck”bool · Default: false
Before a hosted tool runs, asks a small model whether the message concerns your application. The check runs once per turn, and only when a hosted tool passed the filter. If the check itself fails, because of an error or an unexpected answer, the turn goes on. When the check says that the message is not about your application, the agent is told that the hosted tools are not for this request. It still answers with your own actions when the request is about your application.
HostedToolDomainScope
Section titled “HostedToolDomainScope”string? · Default: null
The topic the off-topic check judges against: what counts as being about your application. null derives it from AppName, AppDescription and the page names. When hosted tools are on, the derived text also lists the enabled capabilities, and says that they do not widen the topic. RefuseOutOfScope uses the text you set, as written.
HostedToolDomainClassifier
Section titled “HostedToolDomainClassifier”Func<string, CancellationToken, Task<bool>>? · Default: null
Replaces the model call of the off-topic check with your own decision: return true when the message is about your application.
MaxHostedToolCallsPerSession
Section titled “MaxHostedToolCallsPerSession”int · Default: 0
A hard cap on hosted-tool calls per session. Beyond it, hosted tools are no longer offered to the model. 0 means no cap. Over SignalR the session is the connection, while each request to /mentor/chat, GET or POST, is a session of its own.
Tokens and cost
Section titled “Tokens and cost”These options reduce the tokens sent to the model on each call, and so the cost.
EnableToolFiltering
Section titled “EnableToolFiltering”bool · Default: false
Sends the model only the tools relevant to the message, by embedding similarity. The core tools are always sent: navigation, memory, delegation to specialists and teams, skills and UI actions. Needs EmbeddingGenerator and ChatClient: without them, every tool is sent and a warning is logged.
The embedding ranks the actions well, but its score is not calibrated: a question that needs data can score below a greeting. So the filter does not rely on the threshold alone:
- When no action scores above
ToolFilterMinScore, the three best-ranked actions that need no confirmation and no role are sent anyway, withinToolFilterMaxTools. An MCP tool qualifies only when its server marks itreadOnlyHint. This adds about 80 input tokens to each model call on such turns, greetings included. - When every selected action needs confirmation, up to three of the best-ranked actions that do not need it are sent with them, within
ToolFilterMaxTools. - When a single selected action needs no confirmation, it is sent alone, unless
ToolFilterMinToolsasks for more.
An action needs confirmation when it has RequiresConfirmation, when RequiresApproval matches it, when it comes from a server with MentorMcpServer.RequiresConfirmation, or when it is a [MentorAction] that RequireConfirmationForWrites makes ask. The filter reads these declarations even when RequireConfirmation is false. An action without confirmation can therefore reach the model on any message. Let every action that changes data ask: a [MentorAction] does by default, but a method with [Description] alone does not.
A message that matches no action carries the actions that the previous message selected. So the answer to the agent's own question, such as "Yes, go ahead", still arrives with the action that the question was about. The actions are carried one message back only, never twice, and an action that needs confirmation is never carried alone. A new or restored conversation carries nothing.
Two opt-in options use the selection of the filter: RequireLookupForRecordQuestions and RequireActionForChangeRequests.
ToolFilterMaxTools
Section titled “ToolFilterMaxTools”int · Default: 12
The maximum number of matched tools sent, in addition to the core tools.
ToolFilterMinTools
Section titled “ToolFilterMinTools”int · Default: 0
Once one action scores above ToolFilterMinScore, at least this many of the best-ranked actions are sent, up to ToolFilterMaxTools. With 0, the threshold alone decides. It is a trade-off. It can add the read action that the model needed. It can also add a wrong action that the model picks instead. You do not need it to keep an action that needs confirmation from reaching the model alone: EnableToolFiltering already sends other actions with it. It does not apply to a message where no action scores above ToolFilterMinScore: that message gets the three best-ranked actions that need no confirmation and no role.
ToolFilterMinScore
Section titled “ToolFilterMinScore”float · Default: 0.35
The minimum cosine similarity, from 0 to 1, for a tool to count as relevant. Higher is stricter. The line decides which actions match, not whether a message needs an action: see EnableToolFiltering.
RequireLookupForRecordQuestions
Section titled “RequireLookupForRecordQuestions”bool · Default: false
Makes the agent read a value before it answers a question about your records. A classifier model reads each message. When it says that the message asks for a value of your records (a price, a stock level, the status of an order), the first model call must call a read-only action. It must be one that the tool filter selected for that message. The agent can also hand the request to a specialist or a team. It then writes the reply from what the action returned.
- Which actions. Those you declared read-only, with
ReadOnlyorIsReadOnlyAction, and the tools that a connected MCP server marksreadOnlyHint. An action that needs confirmation or a role is never required. - What it needs.
EnableToolFiltering, anEmbeddingGenerator, aChatClientand at least one declared read. Otherwise the option has no effect, and a startup warning says so. - What it costs. One small classifier call on each turn whose selection holds a declared read. Because tool filtering also sends reads when nothing matches, that is nearly every turn. The call runs on
ClassifierChatClientwhen you set one, withinSafetyCheckTimeout. The reply starts after the result of the action, so aProactivesentence such as "I am looking it up" no longer comes first. - When it does not force. A message addressed by name to one of your specialists, teams or remote agents is not forced. If the classifier fails, times out or gives an answer it cannot read, the turn runs as it would without the option.
RequireActionForChangeRequests
Section titled “RequireActionForChangeRequests”bool · Default: false
Makes the agent start a change with the action itself. The confirmation box then comes before any sentence. Without it, the model can answer "Stock updated" without calling anything: no box appears, and nothing changes.
A classifier model reads each message. It checks two things: whether the message asks to carry out one of your actions that need confirmation, and whether the message gives every input that the action needs. If both are true, the first model call must call one of those actions, chosen from the ones that the tool filter selected for that message. The agent can also hand the request to a specialist or a team. When the message asks for one of your [MentorPage] pages, the first call must be navigate_to.
- A request that leaves something out is not forced. The classifier sees the inputs that each action requires. A request is not complete when an input is missing, when the record is only described ("cancel the last order"), when a name is given where the input is an ID, or when the new value depends on the current one ("add 5 units"). The agent may then ask, as it would without the option. An input counts as needed only when the action's schema marks it required.
- Which actions. Only actions that show a confirmation box: confirmation declared with
RequiresConfirmation,RequiresApprovalorMentorMcpServer.RequiresConfirmation, or asked by default for a[MentorAction]that changes data (RequireConfirmationForWrites), andRequireConfirmationon. An action is never required when its input schema cannot be shown faithfully: a schema with$refor a combination of schemas, or an MCP tool that marks no parameter as required. - With
HitlMode.Native. No rule ofAutoApprovalRulesis consulted for a required call, so the box always appears. - Pages. A page that your application does not have, or something within the page that is already open, is not forced. A request from another agent never has to navigate.
- What it needs and costs.
EnableToolFilteringand anEmbeddingGenerator. One small classifier call on each turn while the application has a page, or the message selected such an action. WithRequireLookupForRecordQuestionson as well, one call answers both. A startup warning says when the option has no effect, or covers page requests only.
The turn that answers a confirmation left open by Stop is never forced.
EnableCompaction
Section titled “EnableCompaction”bool · Default: false
Shortens a long conversation history before each model call, without calling a model: old tool results are collapsed, and the last CompactionMaxTurns turns are kept. It changes what is sent to the model, never the conversation that is stored: the history provider and the session snapshots keep every message. It works with ChatClient and a history kept by your application: the built-in provider, ChatHistoryProviderFactory or ChatHistoryProvider. With UseServiceManagedHistory it is not installed.
CompactionTokenThreshold
Section titled “CompactionTokenThreshold”int · Default: 4000
The size of the history, in tokens, at which compaction starts. If the history is still larger after compaction, it is truncated to this size.
CompactionMaxTurns
Section titled “CompactionMaxTurns”int · Default: 8
The recent user turns kept intact.
Model routing and classifier
Section titled “Model routing and classifier”Model routing sends the turns that need it to a stronger, more expensive model, StrongChatClient, and keeps the others on ChatClient. ClassifierChatClient is the model for MentorAgent's own short decisions: a small, fast model is enough.
StrongChatClient
Section titled “StrongChatClient”IChatClient? · Default: null
A stronger, more expensive model for the turns that need it; ChatClient stays the default. Routing also needs what RoutingStrategy requires: otherwise a warning is logged and every turn stays on ChatClient.
RoutingStrategy
Section titled “RoutingStrategy”MentorRoutingStrategy · Default: Custom
How MentorAgent chooses between ChatClient and StrongChatClient:
Custom: calls yourUseStrongModelAsyncorUseStrongModel.Semantic: compares the message withRoutingComplexExemplars. NeedsEmbeddingGenerator.Classifier: asks a small model,RoutingClassifierClient, with one extra call per turn.Cascade: answers with the cheap model first, and runs the turn again on the strong model when the answer is not good enough. This works only on calls that do not stream. Chat turns stream, so thereCascadedecides likeClassifier.
UseStrongModelAsync
Section titled “UseStrongModelAsync”Func<IReadOnlyList<ChatMessage>, CancellationToken, Task<bool>>? · Default: null
Custom only: your router. It sees the whole conversation; return true to use StrongChatClient. It wins over UseStrongModel.
UseStrongModel
Section titled “UseStrongModel”Func<string, bool>? · Default: null
Custom only: a synchronous predicate on the latest user message. Prefer UseStrongModelAsync.
RoutingComplexExemplars
Section titled “RoutingComplexExemplars”IReadOnlyList<string>? · Default: null
Semantic only: example turns that deserve the strong model. null uses a built-in multilingual set.
RoutingThreshold
Section titled “RoutingThreshold”float · Default: 0.35
Semantic only: the similarity at which a turn is escalated. Higher is stricter.
RoutingClassifierClient
Section titled “RoutingClassifierClient”IChatClient? · Default: null
Classifier and Cascade only: the client that judges the turn. null uses ChatClient.
ClassifierChatClient
Section titled “ClassifierChatClient”IChatClient? · Default: null
The client for MentorAgent's own small decisions:
- the input and output safety checks;
- the off-topic checks of hosted tools and of
RefuseOutOfScope; - the fact extraction of
MemoryAutoCapture; - the grounding check of A2A replies;
- the question behind
RequireLookupForRecordQuestionsandRequireActionForChangeRequests, asked at temperature 0.
Most of these calls run before the user sees the reply, so point it at a small, fast deployment. null uses ChatClient. With Agent and no ChatClient, the safety checks run only when this is set.
Observability and dashboard
Section titled “Observability and dashboard”EnableObservability
Section titled “EnableObservability”bool · Default: false
Emits OpenTelemetry traces and metrics that follow the OpenTelemetry conventions for generative AI (GenAI), plus MentorAgent's own spans and counters.
ObservabilityIncludeSensitiveData
Section titled “ObservabilityIncludeSensitiveData”bool · Default: false
Includes prompt and response content in the telemetry. Development only.
ObservabilitySourceName
Section titled “ObservabilitySourceName”string · Default: "MentorAgent"
The name of the ActivitySource and of the Meter: add it with .AddSource(name).AddMeter(name). An exporter that listens on another name receives nothing.
ModelPricing
Section titled “ModelPricing”IReadOnlyDictionary<string, ModelPrice>? · Default: null
Token prices per model, for the dashboard's cost estimate. MentorAgent ships no prices. Enter them under the model id that the dashboard shows; on Azure OpenAI, that id is the deployment name. See ModelPrice.
DashboardRole
Section titled “DashboardRole”string · Default: "Admin"
The role that GET /mentor/admin/metrics of Novior.MentorAgent.Server requires; "" leaves it open, for development only. The MentorDashboard component does not check it: protect the page that hosts it.
MetricsPersistenceInterval
Section titled “MetricsPersistenceInterval”TimeSpan · Default: 00:00:30
How often the metrics are saved to a registered IMentorMetricsStore; they are also saved on shutdown. Without a store the metrics live in RAM and restart from zero.
MetricsRetention
Section titled “MetricsRetention”TimeSpan · Default: 7.00:00:00
How far back the dashboard keeps its hourly time series: seven days.
MentorMcpServer
Section titled “MentorMcpServer”An entry of McpServers: an MCP server your application connects to, over HTTP or by starting a local process.
MentorMcpServer.Name
Section titled “MentorMcpServer.Name”string · Required
The server's name, shown in the MCP status badge.
MentorMcpServer.ServerUrl
Section titled “MentorMcpServer.ServerUrl”string? · Default: null
The endpoint of an HTTP MCP server. Set this or Command.
MentorMcpServer.Command
Section titled “MentorMcpServer.Command”string? · Default: null
The executable of a local server that talks over stdio, for example npx. On Windows, script launchers such as npx run through cmd.exe /c for you.
MentorMcpServer.Arguments
Section titled “MentorMcpServer.Arguments”IList<string>? · Default: null
The command-line arguments of the local process.
MentorMcpServer.EnvironmentVariables
Section titled “MentorMcpServer.EnvironmentVariables”IDictionary<string, string>? · Default: null
Environment variables for the local process.
MentorMcpServer.AllowedTools
Section titled “MentorMcpServer.AllowedTools”string[]? · Default: null
The only tools to take from the server. null takes them all.
MentorMcpServer.RequiresConfirmation
Section titled “MentorMcpServer.RequiresConfirmation”bool · Default: false
Asks the user to confirm every call to a tool of this server.
MentorMcpServer.Shared
Section titled “MentorMcpServer.Shared”bool? · Default: null
Whether one connection serves the whole process. null decides by transport: a ServerUrl server is shared, a Command server gets one process per session. Set true only for a local server you know is stateless.
MentorHostedMcpServer
Section titled “MentorHostedMcpServer”An entry of HostedMcpServers: a remote MCP server the model provider connects to. Your process never talks to it.
MentorHostedMcpServer.Name
Section titled “MentorHostedMcpServer.Name”string · Required
The identifier the provider uses for the server. The model sees it.
MentorHostedMcpServer.Url
Section titled “MentorHostedMcpServer.Url”string · Required
The address of the server. The provider connects to it, so it must be reachable from the provider's network: localhost does not work.
MentorHostedMcpServer.Description
Section titled “MentorHostedMcpServer.Description”string? · Default: null
A description passed to the provider, for more context.
MentorHostedMcpServer.AllowedTools
Section titled “MentorHostedMcpServer.AllowedTools”IList<string>? · Default: null
The only tools the provider may call. null allows them all; prefer a list for a server you do not control.
MentorHostedMcpServer.RequireApproval
Section titled “MentorHostedMcpServer.RequireApproval”bool · Default: true
Every call needs the user's approval, shown in the usual confirmation box. Set false only for a read-only server you trust.
MentorHostedMcpServer.AlwaysRequireApprovalTools
Section titled “MentorHostedMcpServer.AlwaysRequireApprovalTools”IList<string>? · Default: null
Tools that always need approval. This list wins over RequireApproval.
MentorHostedMcpServer.NeverRequireApprovalTools
Section titled “MentorHostedMcpServer.NeverRequireApprovalTools”IList<string>? · Default: null
Tools that never need approval. This list wins over RequireApproval.
MentorHostedMcpServer.Headers
Section titled “MentorHostedMcpServer.Headers”IDictionary<string, string>? · Default: null
HTTP headers that the provider sends to the server, for example an authorization token. They leave your process: use a token with few permissions that expires soon.
MentorRemoteAgent
Section titled “MentorRemoteAgent”An entry of RemoteAgents: an A2A agent the coordinator can hand requests to.
A remote agent has no role check of its own: any user of your application can reach it through route_to_specialist. To restrict it, do one of these:
- protect the
/a2aendpoint on the remote host and give roles to the actions there; - do not configure the agent on hosts whose users may not use it.
The remote host receives the credentials in Headers, and they are the same for every user of your application. So the roles on the remote host limit what your application may do there. They do not limit which of your users may do it.
MentorRemoteAgent.Name
Section titled “MentorRemoteAgent.Name”string · Required
The agent's name in the handoff graph and in the coordinator's prompt. It must be unique.
MentorRemoteAgent.Description
Section titled “MentorRemoteAgent.Description”string · Required
What the agent does. The coordinator reads it to decide when to hand a request to it.
MentorRemoteAgent.AgentCardUrl
Section titled “MentorRemoteAgent.AgentCardUrl”string · Required
The base URL of the agent, without /.well-known/agent-card.json: the SDK adds it.
MentorRemoteAgent.Headers
Section titled “MentorRemoteAgent.Headers”Dictionary<string, string>? · Default: null
HTTP headers sent with the card request and with every task, for example Authorization.
AgentCardInfo
Section titled “AgentCardInfo”The value of AgentCard: extra fields of the card served at /.well-known/agent-card.json.
AgentCardInfo.Version
Section titled “AgentCardInfo.Version”string · Default: "1.0.0"
The agent version published on the card.
AgentCardInfo.IconUrl
Section titled “AgentCardInfo.IconUrl”string? · Default: null
The URL of the agent's icon.
AgentCardInfo.Provider
Section titled “AgentCardInfo.Provider”string? · Default: null
The provider or organization name.
AgentCardInfo.DocumentationUrl
Section titled “AgentCardInfo.DocumentationUrl”string? · Default: null
The URL of the agent's documentation.
AgentCardInfo.Tags
Section titled “AgentCardInfo.Tags”string[]? · Default: null
Reserved: it is not published on the card.
ModelPrice
Section titled “ModelPrice”A value of ModelPricing, created with new ModelPrice(InputPer1M, OutputPer1M). Prices are in your billing currency, per million tokens.
ModelPrice.InputPer1M
Section titled “ModelPrice.InputPer1M”decimal · Required
The price of one million input tokens.
ModelPrice.OutputPer1M
Section titled “ModelPrice.OutputPer1M”decimal · Required
The price of one million output tokens.
MentorAgentBlazorOptions
Section titled “MentorAgentBlazorOptions”In a Blazor WebAssembly or Auto client, AddMentorAgentBlazor(options => …) configures the widget and the connection to the server's hub. The model, the actions and every rule stay in MentorOptions, on the server. See option B of Blazor WebAssembly and Auto.
MentorAgentBlazorOptions.HubUrl
Section titled “MentorAgentBlazorOptions.HubUrl”string · Default: "/mentor-hub"
The URL of the Novior.MentorAgent.Server SignalR hub. A relative value, such as the default, is resolved against the base address of the page, as a browser does: /mentor-hub at the root of the origin, and mentor-hub under the base path of the app. Use a relative value when the server also serves the client. For a server on another origin, set its absolute URL.
If the URL is absolute, the widget also sends Stop (/mentor/cancel) and the answers to confirmations (/mentor/approve) to the same origin. If it is relative, they resolve against the BaseAddress of the HttpClient of the client. The widget sends them through an HttpClient that you register: the client project of a Blazor Web App has none.
MentorAgentBlazorOptions.AccessTokenProvider
Section titled “MentorAgentBlazorOptions.AccessTokenProvider”Func<Task<string?>>? · Default: null
Returns the bearer token for the hub. It is read on connect and on every reconnect, and sent with every Stop and confirmation request. Without it every user is anonymous to the server: RequiredRoles actions are refused, and memory and rate limit follow the server's AnonymousIdentity.
MentorAgentBlazorOptions.ConfigureConnection
Section titled “MentorAgentBlazorOptions.ConfigureConnection”Action<HttpConnectionOptions>? · Default: null
Changes the hub's connection options: headers, transports, cookies. It runs after AccessTokenProvider.
MentorAgentBlazorOptions.BotName
Section titled “MentorAgentBlazorOptions.BotName”string · Default: "Mentor AI"
The name shown in the widget header.
MentorAgentBlazorOptions.WelcomeMessage
Section titled “MentorAgentBlazorOptions.WelcomeMessage”string? · Default: null
The message shown while the chat is empty. It is rendered as HTML, so never build it from user input.
MentorAgentBlazorOptions.AvatarUrl
Section titled “MentorAgentBlazorOptions.AvatarUrl”string? · Default: null
The URL of the avatar shown in the widget.
MentorAgentBlazorOptions.InputPlaceholder
Section titled “MentorAgentBlazorOptions.InputPlaceholder”string? · Default: null
The placeholder of the input box. null uses the text in the language of Language.
MentorAgentBlazorOptions.Theme
Section titled “MentorAgentBlazorOptions.Theme”MentorTheme · Default: Default
The widget's theme, as Theme on the server.
MentorAgentBlazorOptions.Position
Section titled “MentorAgentBlazorOptions.Position”ChatPosition · Default: BottomRight
Where the widget sits, as Position on the server.
MentorAgentBlazorOptions.PrimaryColor
Section titled “MentorAgentBlazorOptions.PrimaryColor”string? · Default: null
An accent color in hex.
MentorAgentBlazorOptions.Language
Section titled “MentorAgentBlazorOptions.Language”MentorLanguage · Default: English
The language of the widget's texts. The language of the replies is Language on the server.
MentorAgentBlazorOptions.EnableVoiceInput
Section titled “MentorAgentBlazorOptions.EnableVoiceInput”bool · Default: false
Shows the microphone button.
MentorAgentBlazorOptions.EnableVoiceOutput
Section titled “MentorAgentBlazorOptions.EnableVoiceOutput”bool · Default: false
Reads replies aloud.
MentorAgentBlazorOptions.VoiceStreaming
Section titled “MentorAgentBlazorOptions.VoiceStreaming”bool · Default: true
Speaks each sentence as it streams.
MentorAgentBlazorOptions.VoiceBargeIn
Section titled “MentorAgentBlazorOptions.VoiceBargeIn”bool · Default: true
Stops the spoken answer when the user acts, as VoiceBargeIn on the server.
MentorAgentBlazorOptions.VoiceHandsFree
Section titled “MentorAgentBlazorOptions.VoiceHandsFree”bool · Default: false
Lets the user talk without touching the widget, as VoiceHandsFree on the server. Ignored unless both voice options are on.
MentorAgentBlazorOptions.VoiceRate
Section titled “MentorAgentBlazorOptions.VoiceRate”double · Default: 1.0
The speech rate; the useful range is about 0.5 to 2.0.
MentorAgentBlazorOptions.EnableSuggestions
Section titled “MentorAgentBlazorOptions.EnableSuggestions”bool · Default: false
Shows suggestion chips in the welcome panel. Off by default here, unlike the server's option.
MentorAgentBlazorOptions.EnableOnboardingTour
Section titled “MentorAgentBlazorOptions.EnableOnboardingTour”bool · Default: false
Shows the guided tour on first open, with the steps fetched from TourUrl. The server answers GET /mentor/tour even when its own EnableOnboardingTour is false.
MentorAgentBlazorOptions.TourUrl
Section titled “MentorAgentBlazorOptions.TourUrl”string · Default: "/mentor/tour"
Where the tour steps come from. A relative value is resolved against the origin of HubUrl when that is absolute, otherwise against the app's base address.
MentorAgentBlazorOptions.EnableImageInput
Section titled “MentorAgentBlazorOptions.EnableImageInput”bool · Default: false
Shows the image attachment controls. The server's EnableImageInput must be on too: that is where images are checked.
MentorAgentBlazorOptions.MaxImageBytes
Section titled “MentorAgentBlazorOptions.MaxImageBytes”int · Default: 4194304
The size cap per image in the client, 4 MB. Keep it equal to the server's option.
MentorAgentBlazorOptions.MaxImagesPerMessage
Section titled “MentorAgentBlazorOptions.MaxImagesPerMessage”int · Default: 4
The cap on images per message in the client. Keep it equal to the server's option.
MentorAgentBlazorOptions.AllowedImageTypes
Section titled “MentorAgentBlazorOptions.AllowedImageTypes”List<string> · Default: ["image/png", "image/jpeg", "image/gif", "image/webp"]
The MIME allow-list in the client. Keep it equal to the server's option.
MentorAgentBlazorOptions.ShowRagSources
Section titled “MentorAgentBlazorOptions.ShowRagSources”bool · Default: false
Shows citation chips under the agent's replies.
MentorAgentBlazorOptions.ShowHostedToolsStatus
Section titled “MentorAgentBlazorOptions.ShowHostedToolsStatus”bool · Default: false
Shows the badge of the active hosted tools.
MentorAgentBlazorOptions.HostedTools
Section titled “MentorAgentBlazorOptions.HostedTools”MentorHostedTools · Default: None
Leave it unset. The widget uses it only until the connection is up; then the server sends the hosted tools it really has, and the widget uses those.
MentorAgentBlazorOptions.ShowMcpStatus
Section titled “MentorAgentBlazorOptions.ShowMcpStatus”bool · Default: false
Shows the MCP status badge.
MentorAgentBlazorOptions.HasMcpServers
Section titled “MentorAgentBlazorOptions.HasMcpServers”bool · Default: false
Tells the widget that the server has MCP servers, which enables the MCP badge.
MentorAgentBlazorOptions.McpServerNames
Section titled “MentorAgentBlazorOptions.McpServerNames”List<string> · Default: empty
The names of the server's MCP servers, shown as connecting until their status arrives.
MentorAgentBlazorOptions.ShowA2AStatus
Section titled “MentorAgentBlazorOptions.ShowA2AStatus”bool · Default: false
Shows the badge of the remote A2A agents.
MentorAgentBlazorOptions.HasRemoteAgents
Section titled “MentorAgentBlazorOptions.HasRemoteAgents”bool · Default: false
Tells the widget that the server has remote agents, which enables the A2A badge.
MentorAgentBlazorOptions.RemoteAgentDisplays
Section titled “MentorAgentBlazorOptions.RemoteAgentDisplays”List<AgentDisplayInfo> · Default: empty
The remote agents listed in the A2A badge, one AgentDisplayInfo each.
AgentDisplayInfo
Section titled “AgentDisplayInfo”A value of RemoteAgentDisplays: a remote agent as the WebAssembly widget shows it in the A2A detail bar. It only drives the display; the remote agents themselves are configured on the server, in RemoteAgents.
AgentDisplayInfo.Name
Section titled “AgentDisplayInfo.Name”string · Default: ""
The agent's name in the detail bar.
AgentDisplayInfo.AgentCardUrl
Section titled “AgentDisplayInfo.AgentCardUrl”string? · Default: null
The address shown next to the name, usually the agent's base URL, as in MentorRemoteAgent.AgentCardUrl.
MentorDeclarativeOptions
Section titled “MentorDeclarativeOptions”AddMentorAgentDeclarative(o => …) tells Novior.MentorAgent.Declarative where to find agents written in YAML. A definition chooses the model, writes the instructions and names the tools, so treat it as code. See Specialists in YAML.
MentorDeclarativeOptions.Directory
Section titled “MentorDeclarativeOptions.Directory”string? · Default: null
The folder to scan, absolute or relative to the application's base directory. Use a path that ships with the application, never an upload folder or a path built from a request.
MentorDeclarativeOptions.SearchPattern
Section titled “MentorDeclarativeOptions.SearchPattern”string · Default: "*.agent.yaml"
The file pattern inside Directory.
MentorDeclarativeOptions.Recursive
Section titled “MentorDeclarativeOptions.Recursive”bool · Default: false
Scans the sub-folders too.
MentorDeclarativeOptions.Definitions
Section titled “MentorDeclarativeOptions.Definitions”IList<string> · Default: empty
YAML definitions passed as text, for example from a database. They load before the files of Directory. Add to the list: it cannot be replaced.
MentorDeclarativeOptions.ConfigurationSection
Section titled “MentorDeclarativeOptions.ConfigurationSection”string? · Default: null
The configuration section whose values a definition may reference. null exposes no configuration. Name one section, never the whole configuration: a single key that is not a valid Power Fx name stops every definition from loading.
See also
Section titled “See also”- Attributes — The parameters of MentorAction, MentorAgent, MentorTeam, TeamMember, MentorPage and MentorSkill, with their defaults and rules.
- Roles, confirmation and governance — How MentorAgent checks roles and asks for confirmation before an action runs, on every channel, and what it leaves to your code.
- Production checklist — Settings to review before you go to production: governance defaults, safety check, rate limits, cost and routing, history, observability, and outgoing data.
