From monocloud
Use when calling the MonoCloud Management API from .NET — installing or configuring the `MonoCloud.Management` NuGet package, constructing `MonoCloudManagementClient` (direct or via DI with `AddMonoCloudManagementClient`), calling resource clients (`Users`, `Clients`, `Groups`, `Resources`, `Keys`, `Logs`, `Options`, `Branding`, `TrustStores`), reading `MonoCloudResponse<T>` (with `PageModel` for paginated results), handling `MonoCloudException` subclasses, or troubleshooting `MonoCloud:Management:Domain` / `MonoCloud:Management:ApiKey` / 401 / 403 / validation errors.
How this skill is triggered — by the user, by Claude, or both
Slash command
/monocloud:monocloud-management-dotnetThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Typed .NET SDK for the MonoCloud Management API. Use it to programmatically manage users, applications, groups, API resources, sign-in options, branding, logs, keys, and trust stores from .NET (Framework 4.6.2+, .NET Standard 2.0, or modern .NET).
MonoCloud.Management)Typed .NET SDK for the MonoCloud Management API. Use it to programmatically manage users, applications, groups, API resources, sign-in options, branding, logs, keys, and trust stores from .NET (Framework 4.6.2+, .NET Standard 2.0, or modern .NET).
Use: MonoCloud.Management NuGet package.
This is not the same as:
MonoCloud.AspNetCore.Authentication family (user-facing OIDC auth — outside this skill).MonoCloud.Cedar (policy / authorization engine — outside this skill).If code references MonoCloud.Management.Core directly, that's the internal core package. App code should depend only on MonoCloud.Management — the core types (MonoCloudConfig, MonoCloudResponse<T>, MonoCloudException, etc.) are accessible via using MonoCloud.Management;.
Install-Package MonoCloud.Management
dotnet add package MonoCloud.Management
Supported targets: .NET Framework 4.6.2+, .NET Standard 2.0, .NET 6.0+ (anything that consumes netstandard2.0).
A Management API key (generated in the MonoCloud dashboard → Settings → API Keys) is required. Treat it like a root credential:
IConfiguration (appsettings.json + environment variables / User Secrets / Key Vault / etc.).The recommended path is IConfiguration + the DI extension. Configuration is read from the section MonoCloud:Management.
| Key | Required? | Purpose |
|---|---|---|
MonoCloud:Management:Domain | yes | Tenant URL, e.g. https://acme.us.monocloud.app |
MonoCloud:Management:ApiKey | yes | Management API key |
MonoCloud:Management:Timeout | no | Request timeout in seconds |
In Linux/CI environments, set these via env vars using the standard ASP.NET Core mapping:
MonoCloud__Management__DomainMonoCloud__Management__ApiKeyMonoCloud__Management__TimeoutNever hardcode the API key in appsettings.json that ships with the app. Use User Secrets locally and a secret manager in production.
appsettings.Development.json (local dev only; use User Secrets for the API key):
{
"MonoCloud": {
"Management": {
"Domain": "https://your-tenant.us.monocloud.app",
"Timeout": "30"
}
}
}
Program.cs:
using MonoCloud.Management;
var builder = WebApplication.CreateBuilder(args);
// Reads the MonoCloud:Management section from IConfiguration.
builder.Services.AddMonoCloudManagementClient(builder.Configuration);
var app = builder.Build();
app.MapGet("/users", async (MonoCloudManagementClient management) =>
{
var response = await management.Users.GetAllUsersAsync(page: 1, size: 25);
return Results.Ok(response.Result);
});
app.Run();
Inject MonoCloudManagementClient anywhere it's needed. The DI extension registers it as transient, backed by IHttpClientFactory (so connection pooling, retries, etc. layer cleanly on top).
For console apps, background workers, or scenarios without DI:
using MonoCloud.Management;
var config = new MonoCloudConfig(
domain: Environment.GetEnvironmentVariable("MC_MANAGEMENT_DOMAIN")!,
apiKey: Environment.GetEnvironmentVariable("MC_MANAGEMENT_API_KEY")!,
timeout: TimeSpan.FromSeconds(30) // optional
);
var management = new MonoCloudManagementClient(config);
var response = await management.Users.GetAllUsersAsync(1, 25);
MonoCloudManagementClient also accepts an HttpClient directly — useful for integration tests with a test server:
var http = new HttpClient { BaseAddress = new Uri("https://example.com/api/") };
http.DefaultRequestHeaders.Add("X-API-KEY", "test-key");
var management = new MonoCloudManagementClient(http);
Authentication happens via the X-API-KEY header — the SDK adds it automatically when you use MonoCloudConfig.
AddMonoCloudManagementClient also takes an Action<MonoCloudManagementOptions> (alone, or alongside IConfiguration). The action's values override the configuration.
builder.Services.AddMonoCloudManagementClient(builder.Configuration, options =>
{
options.ApiKey = builder.Configuration["Secrets:MonoCloudApiKey"];
options.Timeout = TimeSpan.FromSeconds(60);
});
MonoCloudManagementClient exposes one property per Management API resource area:
| Property | Resource | Backing type |
|---|---|---|
.Branding | Branding | BrandingClient |
.Clients | OAuth applications | ClientsClient |
.Groups | Groups | GroupsClient |
.Keys | Signing keys | KeysClient |
.Logs | Audit logs | LogsClient |
.Options | Tenant options | OptionsClient |
.Resources | API resources | ResourcesClient |
.TrustStores | mTLS trust stores | TrustStoresClient |
.Users | Users | UsersClient |
Each method on a resource client returns Task<MonoCloudResponse<T>> or Task<MonoCloudResponse<T, PageModel>> for paginated lists, plus a CancellationToken parameter. See references/api-surface.md for the full method index.
public class MonoCloudResponse<T>
{
public T Result { get; }
public int StatusCode { get; }
public IReadOnlyDictionary<string, string> Headers { get; }
}
// Paginated variant adds .PageData
public class MonoCloudResponse<T, TPage> : MonoCloudResponse<T>
{
public TPage? PageData { get; } // PageModel for list endpoints
}
public class PageModel
{
public int TotalCount { get; }
public int PageSize { get; }
public int CurrentPage { get; }
public bool HasNext { get; }
public bool HasPrevious { get; }
}
async IAsyncEnumerable<UserSummary> EachUserAsync(MonoCloudManagementClient management, CancellationToken ct)
{
var page = 1;
while (true)
{
var response = await management.Users.GetAllUsersAsync(page, size: 100, cancellationToken: ct);
foreach (var u in response.Result) yield return u;
if (response.PageData is null || !response.PageData.HasNext) yield break;
page++;
}
}
List methods share the (page, size, filter, sort, cancellationToken) shape:
page — 1-indexed (defaults to 1).size — items per page (defaults to 10).filter — Lucene-style expression (per-endpoint; see API docs).sort — "<field>:<1|-1>" (1 ascending, -1 descending).cancellationToken — optional.var created = await management.Users.CreateUserAsync(new CreateUserRequest
{
Name = "Alice Example"
});
await management.Users.PatchPrivateDataAsync(userId, new UpdatePrivateDataRequest
{
PrivateData = new Dictionary<string, object?> { ["onboarded"] = true, ["plan"] = "pro" }
});
Patch is merge: omitted properties are left alone; set a property to null to clear it.
try
{
var response = await management.Users.FindUserByIdAsync(id);
return response.Result;
}
catch (MonoCloudNotFoundException)
{
return null;
}
await management.Users.DisableUserAsync(id, new DisableUserRequest { /* reason etc */ });
Every non-2xx response throws a typed exception that derives from MonoCloudException:
| Class | Thrown for |
|---|---|
MonoCloudBadRequestException | 400 |
MonoCloudUnauthorizedException | 401 |
MonoCloudPaymentRequiredException | 402 |
MonoCloudForbiddenException | 403 |
MonoCloudNotFoundException | 404 |
MonoCloudConflictException | 409 |
MonoCloudIdentityValidationException | 422 (identity validation) |
MonoCloudKeyValidationException | 422 (key validation) |
MonoCloudModelStateException | 422 (model state) |
MonoCloudResourceExhaustedException | 429 |
MonoCloudServerException | 5xx |
MonoCloudRequestException | network / non-HTTP errors |
MonoCloudException | base — catch as fallback |
try
{
await management.Users.CreateUserAsync(req);
}
catch (MonoCloudConflictException)
{
return Results.Conflict();
}
catch (MonoCloudIdentityValidationException ex)
{
return Results.UnprocessableEntity(ex.Errors);
}
catch (MonoCloudException ex)
{
logger.LogError(ex, "MonoCloud Management API call failed: {Status}", ex.StatusCode);
throw;
}
appsettings.json. Use User Secrets (dotnet user-secrets set "MonoCloud:Management:ApiKey" "...") for dev and a secret manager (Azure Key Vault, AWS Secrets Manager, etc.) in production./api/v1 on Domain. Pass the bare tenant URL — the SDK appends /api/.MonoCloud:Management:Timeout is seconds, mirroring TimeSpan.FromSeconds. Don't use ms here.MonoCloudManagementOptions.Timeout's Seconds vs TotalSeconds. The DI binder uses .Seconds; if you set a 90s timeout in code it will read as 30 (because 90s.Seconds == 30). Use whole-minute multiples or set via config string.Exception everywhere. Catch the specific MonoCloudException subclass — status-driven branching is the point.MonoCloudManagementClient per request when using DI. AddMonoCloudManagementClient already registers it transient over IHttpClientFactory. Don't new it inside controllers.MonoCloud.Management.Core types directly. The core types are re-exported under using MonoCloud.Management; — don't add a project reference to the core package.dotnet add package MonoCloud.Management.MonoCloud:Management:Domain (in appsettings.json or config) and MonoCloud:Management:ApiKey (in User Secrets / Key Vault / env var).Program.cs: builder.Services.AddMonoCloudManagementClient(builder.Configuration).MonoCloudManagementClient and call resource APIs.try/catch against the specific MonoCloudException subclass(es) you handle.node skills/monocloud-management-dotnet/scripts/verify.js to confirm config + package installation.references/api-surface.md — resource-by-resource method index.references/troubleshooting.md — symptom → cause → fix index for the most common failure modes (401s, missing Domain/ApiKey at startup, secret leaks in appsettings.json, the Timeout.Seconds vs .TotalSeconds footgun, hand-newed clients vs DI, generic catch (Exception), single-page reads).npx claudepluginhub monocloud/agent-skills --plugin monocloudProvides CDSS development patterns for drug interaction checking, dose validation, clinical scoring (NEWS2, qSOFA), and alert classification integrated into EMR workflows.