Portal Community

Full Interface Definition

namespace BizFirst.Octopus.Core.Plugins;

/// <summary>
/// Contract for all Octopus plugins. Plugins are registered during application
/// startup and extend the Octopus agent framework with services, tools, and capabilities.
/// </summary>
public interface IOctopusPlugin
{
    /// <summary>
    /// Called during IServiceCollection registration (before the DI container is built).
    /// Use to register DI services, configure options, and add middleware.
    /// Do NOT resolve services here — the container is not built yet.
    /// </summary>
    void OnRegister(IServiceCollection services, OctopusConfig config);

    /// <summary>
    /// Called after the DI container is built, during application start.
    /// Use to resolve registered services, apply database migrations,
    /// register MCP tools, and perform any async initialisation.
    /// </summary>
    Task OnStartAsync(IServiceProvider serviceProvider, CancellationToken ct);

    /// <summary>
    /// Called during application shutdown. Use to dispose resources,
    /// close connections, flush buffers, and perform clean shutdown.
    /// </summary>
    Task OnStopAsync(CancellationToken ct);
}

Method Responsibilities

MethodPhaseCan Resolve Services?Common Actions
OnRegisterBefore container buildNoAddScoped/Singleton, AddDbContext, Configure<TOptions>, AddHttpClient
OnStartAsyncAfter container build, before first requestYesMigrateAsync, Register MCP tools, Connect to external services, seed data
OnStopAsyncApplication shutdownYes (root scope)Dispose IDisposable, flush logs, close connections, release ports

Minimal Plugin Implementation

public class MinimalPlugin : IOctopusPlugin
{
    public void OnRegister(IServiceCollection services, OctopusConfig config)
    {
        // Register your services here
        services.AddScoped<IMyService, MyService>();
    }

    public Task OnStartAsync(IServiceProvider sp, CancellationToken ct)
    {
        // Initialise after DI container is ready
        var myService = sp.GetRequiredService<IMyService>();
        // ... initialise ...
        return Task.CompletedTask;
    }

    public Task OnStopAsync(CancellationToken ct)
    {
        // Clean up resources
        return Task.CompletedTask;
    }
}

OctopusConfig

The OctopusConfig object passed to OnRegister provides access to the application's configuration (appsettings.json), allowing plugins to read their configuration section:

public class OctopusConfig
{
    public IConfiguration    Configuration { get; }
    public IWebHostEnvironment Environment  { get; }

    // Helper to bind a plugin-specific config section
    public T GetSection<T>(string sectionKey) where T : new()
    {
        var obj = new T();
        Configuration.GetSection(sectionKey).Bind(obj);
        return obj;
    }
}

// Usage in OnRegister:
var myConfig = config.GetSection<MyPluginConfig>("MyPlugin");
services.AddSingleton(myConfig);