What a Smart Client plugin actually is
Milestone XProtect Smart Client is the operator-facing console used to view live and recorded video, manage alarms, and work investigations. Out of the box it's a fixed application — but Milestone ships it with an extensibility layer, the MIP SDK (Milestone Integration Platform Software Development Kit), that lets third parties add new functionality without touching Milestone's own code.
A Smart Client plugin is a .NET assembly (a DLL, typically targeting .NET Framework and WPF) that Smart Client discovers and loads at startup from its MIPPlugins folder. Once loaded, the plugin can register one or more plugin types — a new kind of view item that fits inside a camera view grid, a panel docked to the side of the interface, a background service that reacts to events, or a settings page inside Management Client. Every plugin we build at Xplug.in for Milestone XProtect starts from this same extensibility model.
What the MIP SDK provides
The SDK is distributed as a set of .NET assemblies (primarily under the VideoOS.Platform namespace) plus sample projects and documentation, available to registered Milestone MIP partners. The pieces most relevant to Smart Client plugin development are:
- VideoOS.Platform.Client — the base classes for Smart Client extensibility:
PluginDefinition,ViewItemPlugin,ViewItemWpfUserControl,SidePanelPlugin, andBackgroundplugin types. - VideoOS.Platform — configuration access (
Configuration.Instance), the item hierarchy (cameras, servers, views), andEnvironmentManagerfor host/version information. - VideoOS.Platform.Messaging — a publish/subscribe message bus used to pass events between your plugin's components and to react to Smart Client state changes (view changed, item selected, and so on).
Beyond Smart Client, the same SDK covers Event Server plugins (custom event and alarm sources), Recording Server device driver plugins, and Management Client property-page plugins — but this guide focuses on the Smart Client side, which is where most bespoke operator-facing capability gets built.
The plugin entry point: PluginDefinition
Every MIP plugin assembly needs exactly one class that inherits from the abstract PluginDefinition base class. This is the entry point Smart Client instantiates on startup — it identifies the plugin and tells the host application which plugin types it contributes.
using System;
using System.Collections.Generic;
using System.Drawing;
using VideoOS.Platform.Client;
namespace Xplug.SmartClient.Sample
{
public class SamplePluginDefinition : PluginDefinition
{
private static readonly Guid PluginIdValue =
new Guid("6E9C2C2A-6B0A-4B0B-9C2E-2B6F3A7D5E11");
public override Guid Id => PluginIdValue;
public override string Name => "Xplug Sample Plugin";
public override string VersionString => "1.0.0";
public override string Manufacturer => "Xplug.in";
public override List<ViewItemPlugin> ViewItemPlugins =>
new List<ViewItemPlugin> { new SampleViewItemPlugin() };
public override List<SidePanelPlugin> SidePanelPlugins =>
new List<SidePanelPlugin> { new SampleSidePanelPlugin() };
}
}
Smart Client finds this class through reflection when it scans the assembly, so there's no separate registration file to maintain — the PluginDefinition subclass is the manifest. From here, every capability the plugin exposes is declared as a list Smart Client reads on load.
Registering a view item with ViewItemPlugin
A view item is anything an operator can drag into a Smart Client view grid alongside camera panes — a map, a custom dashboard, a search widget. To add a new one, you implement ViewItemPlugin, which describes the item (name, icon, category) and produces the actual WPF control that gets hosted inside the view cell.
using System;
using System.Drawing;
using VideoOS.Platform.Client;
namespace Xplug.SmartClient.Sample
{
public class SampleViewItemPlugin : ViewItemPlugin
{
public override string Name => "Xplug Analytics Panel";
public override Guid Kind => new Guid("2B7C1E10-4C3A-4A7E-9C1D-8E2F6A0B9C33");
public override Guid ScreenSize => ViewItemManager.Size1x1;
public override ViewItemWpfUserControl GenerateViewItemWpfUserControl()
{
return new SampleViewItemWpfUserControl();
}
public override Image Icon => Properties.Resources.PluginIcon;
}
public class SampleViewItemWpfUserControl : ViewItemWpfUserControl
{
public SampleViewItemWpfUserControl()
{
InitializeComponent();
}
public override void Init()
{
// Called once the item has an assigned FQID (the camera,
// view, or item the operator dropped the plugin onto).
base.Init();
}
}
}
The ViewItemWpfUserControl is a regular WPF UserControl under the hood, so anything you'd normally build in WPF — data binding, custom controls, third-party UI libraries — works inside it. What MIP SDK adds is the lifecycle: Init() fires once the control has a Fully Qualified ID (FQID) bound to it, which is how your plugin knows which camera, server, or view item it's actually attached to in that specific view.
Side panels for persistent, view-independent UI
Not every capability belongs inside a view cell. Alarm lists, bookmark managers, and search tools in stock Smart Client are all side panels — UI docked to the edge of the window that stays visible regardless of which view the operator is looking at. SidePanelPlugin follows the same pattern as ViewItemPlugin: declare a name and icon, then hand back the WPF control Smart Client should dock.
using System.Drawing;
using VideoOS.Platform.Client;
namespace Xplug.SmartClient.Sample
{
public class SampleSidePanelPlugin : SidePanelPlugin
{
public override string Name => "Xplug Alerts";
public override Image Icon => Properties.Resources.SidePanelIcon;
public override SidePanel GenerateSidePanel()
{
return new SampleSidePanel();
}
}
}
Side panels are the right fit for anything an operator needs on standby — a live alert feed, a rules dashboard, a chat channel to a response team — rather than something tied to a specific camera or view.
Deployment: getting a plugin from build to running Smart Client
Once the plugin builds cleanly against the SDK's reference assemblies, deployment is largely a matter of getting the DLL (and its dependencies) into the right folder:
- Build in Release configuration, matching the target Smart Client's bitness (x64 for current XProtect releases) and .NET Framework version.
- Copy the output to a subfolder under
%ProgramFiles%\Milestone\XProtect Smart Client\MIPPlugins\<YourPluginName>\, including any third-party dependencies the plugin references. - Restart Smart Client. On startup it scans
MIPPlugins, loads each assembly, and instantiates anyPluginDefinitionsubclass it finds. - Verify the load via Smart Client's About/plugin information dialog, or by checking the client-side MIP SDK log for load errors — a missing dependency or version mismatch against the installed XProtect release is the most common failure at this step.
- For fleet rollout, package the plugin as an MSI or use your existing software-distribution tooling so the same build lands identically across every operator workstation — version drift between Smart Client instances is the single biggest cause of "works on my machine" plugin bugs.
For anything beyond a proof of concept, we also recommend certification through Milestone's MIP Verified programme, which validates the plugin against Milestone's compatibility and stability requirements before it goes into a customer's production environment.
Where this gets hard in practice
The patterns above cover the mechanical side of MIP SDK plugin development, and they're genuinely all you need for a prototype. Where projects usually get harder is everything around that skeleton: handling reconnects and view-switching cleanly inside ViewItemWpfUserControl.Init(), keeping a side panel's state in sync across multiple open Smart Client windows, managing configuration through Configuration.Instance without blocking the UI thread, and packaging a plugin so it survives a Milestone version upgrade without breaking.
This is the part of custom Milestone XProtect plugin development we specialise in at Xplug.in — architecture, MIP Verified certification, and long-term version tracking across XProtect releases, not just the first working build.
Need a Milestone XProtect Smart Client plugin built and certified? Xplug.in is a Milestone MIP Verified partner with 140+ plugins shipped since 2014.
Schedule a technical demo