# Extensions.ServiceCollectionExtensions

> The ServiceCollectionExtensions class of Novior.MentorAgent.Extensions.

- URL: https://docs.mentoragent.net/api/novior-mentoragent-extensions/servicecollectionextensions
- Verified with: MentorAgent 1.2.0
- Last updated: 2026-10-27
- Packages: Novior.MentorAgent

## Definition

Namespace: `Novior.MentorAgent.Extensions`. Package: `Novior.MentorAgent`.

`public static class ServiceCollectionExtensions`

```shell
dotnet add package Novior.MentorAgent
```

## Methods

### `AddMentorActionObserver`

`public static IServiceCollection AddMentorActionObserver<TObserver>(this IServiceCollection services)`

Registers an [`IMentorActionObserver`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentoractionobserver): it receives every decision of the tool gate, for every session and every surface of the process. A singleton, resolved from the application's root services; every observer registered is called, in the order of registration. Registering the same type twice registers it once.

`public static IServiceCollection AddMentorActionObserver(this IServiceCollection services, IMentorActionObserver observer)`

Registers `observer` as an [`IMentorActionObserver`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentoractionobserver): it receives every decision of the tool gate, for every session and every surface of the process.

**Parameters**

- `services`: The services.
- `observer`: The observer, already built.

### `AddMentorActionPolicy`

`public static IServiceCollection AddMentorActionPolicy<TPolicy>(this IServiceCollection services)`

Registers an [`IMentorActionPolicy`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentoractionpolicy): it decides whether a user may use each of the application's actions, and whether each call may run, on every surface. A singleton, resolved from the application's root services; what it needs from the conversation's scope it resolves from `MentorActionRequest.Services`. Every policy registered is asked, in the order of registration. Registering the same type twice registers it once.

`public static IServiceCollection AddMentorActionPolicy(this IServiceCollection services, IMentorActionPolicy policy)`

Registers `policy` as an [`IMentorActionPolicy`](https://docs.mentoragent.net/api/novior-mentoragent-abstractions-interfaces/imentoractionpolicy): it decides whether a user may use each of the application's actions, and whether each call may run, on every surface.

**Parameters**

- `services`: The services.
- `policy`: The policy, already built.

### `AddMentorAgent`

`public static IServiceCollection AddMentorAgent(this IServiceCollection services, Action<MentorOptions> configure)`

Registers MentorAgent in the DI container. Usage in Program.cs:

```text title="Example"
builder.Services.AddMentorAgent(options =>
{
    options.ChatClient  = new OpenAIClient("sk-...").GetChatClient("gpt-4o").AsIChatClient();
    options.AppName     = "MyApp";
    options.Language    = MentorLanguage.Italian;
    options.ScanAssemblies = [typeof(Program).Assembly];
});
```

Optional MCP server (with the Novior.MentorAgent.Server package):

```text title="Example"
options.McpServerEnabled = true;
// then: builder.Services.AddMentorAgentMcp();  and  app.MapMentorAgentMcp();
```

Optional A2A server (with the Novior.MentorAgent.Server package):

```text title="Example"
options.A2AServerEnabled = true;
// then: builder.Services.AddMentorAgentA2A();  and  app.MapMentorAgentA2A();
```

`configure` runs **twice**: once now, on a snapshot, for the options that decide what gets registered — `EnableObservability`, `ObservabilitySourceName`, `McpServerEnabled`, `A2AServerEnabled`, and `AppName` as the MCP server's name — and once more when the options are first built. Set those options in this callback: a `Configure<MentorOptions>` or `PostConfigure` registered afterwards does not reach them. The A2A agent card is built from the real options, when `MapMentorAgentA2A` runs. Keep the callback free of side effects that must happen once. If it throws on the snapshot, those options keep their defaults and a warning reports the exception when the host starts.

The options are validated when a generic host (ASP.NET Core, a worker) starts: an invalid configuration stops it with the reason. Without one (a MAUI app) they are validated the first time they are read.

---

- Previous: [ProtocolServiceCollectionExtensions class](https://docs.mentoragent.net/api/novior-mentoragent-extensions/protocolservicecollectionextensions.md)
- Next: [IMentorMemoryStore interface](https://docs.mentoragent.net/api/novior-mentoragent-memory/imentormemorystore.md)
