Plugins
The OpenBI MCP Server has zero hard dependencies on any specific BI platform. All platform-specific logic ships as plugins — isolated .NET assemblies loaded at runtime using AssemblyLoadContext.
Plugin types
Four extensibility interfaces can be implemented as plugins:
| Interface | Purpose | Resolved from |
|---|---|---|
ISiteConnectionFactory |
Creates connections to a BI platform (download, upload, query) | sites/*.json → siteConnectionFactoryName |
IOpenBIConverterFactory |
Converts platform artifacts ↔ OpenBI model | sites/*.json → siteConverterFactoryName |
ISiteRegistry |
Provides the list of registered sites | appsettings.json → SiteRegistry:ImplementationType |
ISecretsVaultRepository |
Reads connection secrets | appsettings.json → SecretsVault:ImplementationType |
A single plugin DLL can implement multiple interfaces — for example, OpenBI.Connectors.CoCoBI.dll can export both a ISiteConnectionFactory and a custom ISiteRegistry.
Plugin folder layout
Plugins live inside the build output directory, not the project source folder.
bin/Debug/net9.0/
└── plugins/
├── MyOrg.Connectors.MyPlatform/
│ ├── MyOrg.Connectors.MyPlatform.dll
│ ├── MyOrg.Connectors.MyPlatform.deps.json ← required
│ └── (all transitive dependencies)
└── MyOrg.Converters.MyPlatform/
├── MyOrg.Converters.MyPlatform.dll
├── MyOrg.Converters.MyPlatform.deps.json
└── (all transitive dependencies)
Warning
The deps.json file is required. Without it the plugin loader cannot resolve transitive dependencies and the plugin will be skipped with a warning.
Building and installing a plugin
Use dotnet publish to produce the self-contained plugin folder:
# Build connector plugin
dotnet publish MyOrg.Connectors.MyPlatform \
-c Release \
-o "path/to/OpenBI.MCP.Server/bin/Release/net9.0/plugins/MyOrg.Connectors.MyPlatform"
# Build converter plugin
dotnet publish MyOrg.Converters.MyPlatform \
-c Release \
-o "path/to/OpenBI.MCP.Server/bin/Release/net9.0/plugins/MyOrg.Converters.MyPlatform"
For debug builds, replace Release with Debug and adjust the output path accordingly.
How the plugin loader works
At server startup, before any DI resolution, PluginLoader performs the following steps:
- Scans every subdirectory of
{AppContext.BaseDirectory}/plugins/. - For each subdirectory, locates the
*.deps.jsonfile. - Creates an isolated
PluginLoadContext(a customAssemblyLoadContext) backed by anAssemblyDependencyResolverpointing at thatdeps.json. - Loads the primary
*.dllfrom that context. - Reflects all public types that implement any of the four extensibility interfaces.
- Registers them by their assembly-qualified name in the in-memory
PluginTypeRegistry.
Plugins with missing deps.json, missing DLLs, or load errors are skipped with a warning — they do not crash the server.
Shared assembly isolation
Assemblies that form the OpenBI contract boundaries (OpenBI, OpenBI.MCP.Interfaces, OpenBI.Connectors.Interfaces, OpenBI.Converters.Interfaces) are always resolved from the default AssemblyLoadContext. This prevents type identity mismatches when the server checks whether a plugin type implements an interface — both sides must see the exact same Type object.
All other assemblies (vendor SDKs, HTTP clients, etc.) are loaded privately inside the plugin's own ALC, preventing version conflicts between plugins.
Type name format
When referencing a plugin type in appsettings.json or sites/*.json, use the standard .NET assembly-qualified name:
Example:
"siteConnectionFactoryName": "MyOrg.Connectors.MyPlatform.MyConnectionFactory, MyOrg.Connectors.MyPlatform"
You do NOT need the full Version=... suffix — the plugin loader resolves by name only.
Implementing a connector plugin
A minimal connector plugin implements ISiteConnectionFactory from OpenBI.Connectors.Interfaces:
// Reference: OpenBI.Connectors.Interfaces (NuGet)
public class MyPlatformSiteConnectionFactory : ISiteConnectionFactory
{
public string FactoryName => "MyPlatform";
public Task<ISiteConnection> CreateConnectionAsync(
SiteManifest site,
ISecretsVaultRepository secrets,
CancellationToken ct)
{
// Read credentials from secrets, return a connection
return Task.FromResult<ISiteConnection>(new MyPlatformSiteConnection(site, secrets));
}
}
Then reference the package in your .csproj:
See the OpenBI.Connectors.Interfaces package for full interface documentation.