ImageGenMcp.SemanticKernel.Plugin
1.0.0
dotnet add package ImageGenMcp.SemanticKernel.Plugin --version 1.0.0
NuGet\Install-Package ImageGenMcp.SemanticKernel.Plugin -Version 1.0.0
<PackageReference Include="ImageGenMcp.SemanticKernel.Plugin" Version="1.0.0" />
<PackageVersion Include="ImageGenMcp.SemanticKernel.Plugin" Version="1.0.0" />
<PackageReference Include="ImageGenMcp.SemanticKernel.Plugin" />
paket add ImageGenMcp.SemanticKernel.Plugin --version 1.0.0
#r "nuget: ImageGenMcp.SemanticKernel.Plugin, 1.0.0"
#:package ImageGenMcp.SemanticKernel.Plugin@1.0.0
#addin nuget:?package=ImageGenMcp.SemanticKernel.Plugin&version=1.0.0
#tool nuget:?package=ImageGenMcp.SemanticKernel.Plugin&version=1.0.0
ImageGen-MCP-SK-Plugin
A .NET 10 Semantic Kernel plugin that connects SK agents and apps to the
image-gen-mcp server (ImageGen.McpHost)
— a provider-agnostic MCP server for AI image generation supporting Stability AI and
Google Gemini Imagen.
Communication uses raw JSON-RPC 2.0 over stdio (initialize, tools/list, tools/call),
dynamically exposing the server's tools as Kernel functions.
Architecture
ImageGen-MCP-SK-Plugin/
├── src/
│ ├── ImageGenMcp.Core/ # Interfaces, models, exceptions, utilities
│ ├── ImageGenMcp.Infrastructure/ # Stdio client, process manager, serialisation, conversion
│ └── ImageGenMcp.Plugin/ # Semantic Kernel integration, DI extensions
├── tests/
│ └── ImageGenMcp.Tests/ # Unit, integration, and property-based tests
└── samples/
└── ImageGenMcp.Sample/ # Console sample demonstrating full usage
Quick Start
1. Install the MCP server
dotnet tool install --global ImageGen.McpHost --version 0.1.1
2. Set your provider API key
# Stability AI
$env:STABILITY_API_KEY = "sk-..."
# Google Gemini Imagen
$env:GEMINI_API_KEY = "AIza..."
3. Add the NuGet package
dotnet add package ImageGenMcp.SemanticKernel.Plugin
4. Register and use
var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddImageGenMcp(builder.Configuration);
using var host = builder.Build();
var plugin = host.Services.GetRequiredService<ImageGenPlugin>();
await plugin.InitializeAsync();
// Generate an image
var imagePath = await plugin.GenerateImageAsync(
prompt: "A serene mountain lake at golden hour, photorealistic",
aspectRatio: "16:9",
steps: 30);
Console.WriteLine($"Image saved to: {imagePath}");
SK Registration Modes
Expanded mode (recommended for auto function-calling)
Registers every discovered tool as a dedicated Kernel function:
await kernel.RegisterImageGenToolsAsync(host.Services, pluginName: "imagegen");
// Creates kernel functions like: imagegen_image_gen_generate, imagegen_image_gen_info, …
Router mode (typed plugin)
Registers the plugin object directly — gives the planner four well-described functions:
kernel.RegisterImageGenPlugin(host.Services, pluginName: "imagegen");
// Functions: imagegen_generate, imagegen_get_credits, imagegen_info, imagegen_invoke
Configuration
appsettings.json:
{
"ImageGenMcp": {
"ExecutablePath": "imagegen-mcp",
"AdditionalArguments": [],
"ConnectionTimeoutSeconds": 30,
"RequestTimeoutSeconds": 60,
"MaxRetryAttempts": 3,
"BackoffStrategy": "Exponential",
"InitialRetryDelayMs": 1000,
"EnableProcessPooling": true,
"MaxIdleTimeSeconds": 300,
"ToolDefinitionsPath": null,
"EnableMessageLogging": false
}
}
Environment override:
IMAGEGEN_MCP_PATH— overridesExecutablePathat runtime.
Provider keys (read by imagegen-mcp, not by this plugin):
STABILITY_API_KEYGEMINI_API_KEY
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
ExecutablePath |
string | imagegen-mcp |
Path or name of the MCP server executable |
AdditionalArguments |
string[] | [] |
Extra CLI args appended to the process |
ConnectionTimeoutSeconds |
int | 30 |
Timeout for the MCP initialize handshake |
RequestTimeoutSeconds |
int | 60 |
Timeout per tools/call request |
MaxRetryAttempts |
int | 3 |
Retry count for transient failures |
BackoffStrategy |
enum | Exponential |
Linear or Exponential |
InitialRetryDelayMs |
int | 1000 |
Base delay for first retry |
EnableProcessPooling |
bool | true |
Reuse the server process across requests |
MaxIdleTimeSeconds |
int | 300 |
Idle timeout before process shutdown |
ToolDefinitionsPath |
string? | null |
Path to a fallback tool definitions JSON file |
EnableMessageLogging |
bool | false |
Log full JSON-RPC messages at Debug level |
Tool Reference
image_gen_generate
string imagePath = await plugin.GenerateImageAsync(
prompt: "A cat wearing a spacesuit",
aspectRatio: "1:1", // 1:1 | 16:9 | 9:16 | 4:3 | 3:4 | 2:3 | 3:2 | 21:9 | 9:21 | 4:5 | 5:4
steps: 30, // 1–150
seed: 42, // optional, for reproducibility
model: "sd3-large" // optional, provider-specific override
);
image_gen_get_credits
string credits = await plugin.GetCreditsAsync();
// "150.00" (Stability AI) or "N/A" (Gemini)
image_gen_info
string info = await plugin.GetServerInfoAsync();
// "Provider: StabilityAI | Models: sd3-large, core | Output: C:\images"
Dynamic / pass-through
var result = await plugin.InvokeToolAsync(
"image_gen_generate",
new Dictionary<string, object?> { ["prompt"] = "a sunset" });
Error Handling
try
{
await plugin.InitializeAsync();
var path = await plugin.GenerateImageAsync("a cat");
}
catch (ConfigurationException ex)
{
// Bad options — check appsettings.json
}
catch (ProcessException ex)
{
// imagegen-mcp could not start — check installation
}
catch (NetworkException ex)
{
// Transport failure — broken pipe, EOF
}
catch (ImageGenMcp.Core.Exceptions.TimeoutException ex)
{
// Exceeded RequestTimeoutSeconds or ConnectionTimeoutSeconds
}
catch (McpServerException ex)
{
// Server returned JSON-RPC error (ex.ErrorCode, ex.ErrorData)
}
catch (ProtocolException ex)
{
// Malformed JSON-RPC message (ex.MalformedData)
}
catch (ImageGenMcpException ex)
{
// Any other plugin error — base type for all above
}
Health Monitoring
bool healthy = await plugin.PingAsync();
Console.WriteLine($"Connected: {healthy}");
var state = host.Services.GetRequiredService<IMcpClient>().State;
Console.WriteLine($"State: {state}"); // Disconnected | Initializing | Connected | Closed
Custom Type Converters
var converter = host.Services.GetRequiredService<IParameterConverter>();
converter.RegisterConverter(new MyCustomTypeConverter());
public class MyCustomTypeConverter : ITypeConverter<MyType>
{
public object? ToMcp(MyType? value) => value?.ToString();
public MyType? FromMcp(object? value) => value is string s ? MyType.Parse(s) : null;
}
Graceful Degradation
Provide a fallback tool-definitions file when the server is unavailable:
{
"ImageGenMcp": {
"ToolDefinitionsPath": "imagegen-tools.json"
}
}
imagegen-tools.json format:
[
{
"name": "image_gen_generate",
"description": "Generate an AI image from a text prompt",
"inputSchema": {
"type": "object",
"properties": {
"prompt": { "type": "string", "description": "Image description" }
},
"required": ["prompt"]
}
}
]
Technology Stack
- .NET 10 — latest LTS
- C# 13 — file-scoped namespaces, collection expressions,
requiredmembers, source generators - Microsoft.SemanticKernel — AI agent framework integration
- System.Text.Json — source-generated, zero-reflection serialisation
- xUnit + NSubstitute + FsCheck — unit, mock, and property-based testing
Security
- LogSanitizer — automatically redacts Stability AI keys (
sk-…), Gemini keys (AIza…), JWT tokens, Bearer tokens, passwords, and email addresses from all log output. - InputValidator — validates tool names and
image_gen_generateparameters before any network call. - No hardcoded secrets — API keys are read exclusively from environment variables by
imagegen-mcp.
Building & Testing
# Restore
dotnet restore ImageGen-MCP-SK-Plugin.slnx
# Build
dotnet build ImageGen-MCP-SK-Plugin.slnx -c Release
# Test
dotnet test ImageGen-MCP-SK-Plugin.slnx
# Test with coverage
dotnet test ImageGen-MCP-SK-Plugin.slnx --collect:"XPlat Code Coverage" --settings coverlet.runsettings
# Pack NuGet
dotnet pack src/ImageGenMcp.Plugin/ImageGenMcp.Plugin.csproj -c Release -o nupkg
Project Structure Detail
src/ImageGenMcp.Core/
├── Interfaces/ IMcpClient, IParameterConverter, ITypeConverter<T>
├── Models/ McpConnectionState, McpToolDefinition, McpToolParameter,
│ ToolResult, ImageGenerationResult, CreditsResult, ServerInfoResult
├── Exceptions/ ImageGenMcpException (base), ConfigurationException,
│ ProcessException, NetworkException, TimeoutException,
│ McpServerException, ProtocolException
└── Utilities/ LogSanitizer
src/ImageGenMcp.Infrastructure/
├── Client/ StdioMcpClient — JSON-RPC 2.0 over stdio
├── Configuration/ ImageGenMcpOptions, ImageGenMcpOptionsValidator, BackoffStrategy
├── Conversion/ ParameterConverter
├── Process/ ProcessManager
└── Serialization/ JsonRpcMessage, McpJsonContext (source-gen)
src/ImageGenMcp.Plugin/
├── ImageGenPlugin.cs — Main plugin: GenerateImageAsync, GetCreditsAsync,
│ GetServerInfoAsync, InvokeToolAsync
├── Extensions/ ServiceCollectionExtensions, KernelExtensions
├── Mapping/ FunctionMapper — dynamic tool → KernelFunction
└── Validation/ InputValidator
tests/ImageGenMcp.Tests/
├── CoreTests/ LogSanitizerTests, ExceptionTests, ToolResultTests
├── InfrastructureTests/ ParameterConverterTests, ImageGenMcpOptionsTests
└── PluginTests/ InputValidatorTests, ImageGenPluginTests
Acknowledgements
- Built on Microsoft Semantic Kernel
- Connects to image-gen-mcp (
ImageGen.McpHost) - Follows the Model Context Protocol specification
License
MIT — see LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- ImageGenMcp.Core (>= 1.0.0)
- ImageGenMcp.Infrastructure (>= 1.0.0)
- Microsoft.Extensions.Configuration.Binder (>= 10.0.6)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.6)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.6)
- Microsoft.SemanticKernel.Core (>= 1.74.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 109 | 4/17/2026 |