Monocloud management js
Skill monocloud/agent-skills/plugins/monocloud/skills/monocloud-management-js
Official MonoCloud Agent Skills repository.
npx -y skills add monocloud/agent-skills --skill monocloud-management-jsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use when calling the MonoCloud Management API from Node.js / TypeScript — installing or configuring `@monocloud/management`, initializing `MonoCloudManagementClient` via the static `init()` factory with `domain` + `apiKey`, calling the ten resource clients (`users`, `clients`, `groups`, `resources`, `keys`, `logs`, `options`, `branding`, `networkZones`, `trustStores`) — including IP/regional network zones, PKI & SPIFFE (mTLS) trust stores, API access policies, external identity providers, and grants/tokens — reading `.result` and looping paginated lists via `MonoCloudPageResponse.pageData`, handling `MonoCloudException` / `MonoCloudUnauthorizedException` / `MonoCloudPaymentRequiredException` / `MonoCloudIdentityValidationException` subclasses, or troubleshooting `MONOCLOUD_MANAGEMENT_DOMAIN` / `MONOCLOUD_MANAGEMENT_API_KEY` / `MONOCLOUD_MANAGEMENT_TIMEOUT` / 401 / 402 / 403 / 422 validation errors.
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
20.1 KB, ~4.4k tokens by cl100k_base, as published. Nobody here has run it
MonoCloud Management JS SDK (@monocloud/management)
Typed JavaScript / TypeScript SDK for the MonoCloud Management API. Use it to programmatically manage users, applications, groups, API resources, tenant options, branding, logs, signing keys, PKI/SPIFFE trust stores, and network zones in a MonoCloud tenant.
Package identity — read this first
Use: @monocloud/management (this skill). Check package.json before writing code — confirm this is the dependency and note its version.
This is not the same SDK as:
@monocloud/auth-nextjs— Next.js user sessions (different skill:monocloud-auth-nextjs).@monocloud/auth-web-js— browser SPA sessions (different skill:monocloud-web-js).@monocloud/backend-node— API bearer-token validation (different skills:monocloud-auth-express,monocloud-auth-fastify).MonoCloud.Management— the .NET Management SDK (different skill:monocloud-management-dotnet; it uses.Data/.PageDataand PascalCase, not the JS conventions below).
@monocloud/management-core is the internal core package. Applications import from @monocloud/management; the public types (MonoCloudConfig, MonoCloudResponse, Fetcher, IdentityError, and the MonoCloud*Exception classes) are re-exported from the main package. MonoCloudPageResponse, PageModel, and ProblemDetails are NOT re-exported from @monocloud/management — they live in the core package (see Response shape).
Do not invent method names from stale training data. The client is created with a static factory (MonoCloudManagementClient.init()), the constructor is private, and the deserialized body lives on .result (not .data).
Installation
npm install @monocloud/management
Supported Node.js: >= 11.0.0. Requires a global fetch (Node 18+ has it built in; on older runtimes supply your own via the custom fetcher).
Authentication — Management API key
You need a Management API key generated in the MonoCloud dashboard. Treat it like a root credential:
- Never ship it to a browser or commit it to source control.
- Always read it from
process.env(or an equivalent secret store). - A management key is tenant-scoped with full admin permissions.
The key is sent on every request as the X-API-KEY header (the SDK sets this for you).
Environment variables (and config keys)
The SDK can be configured by environment variables or explicit options passed to init(). Explicit options always win; each env var is only consulted when the matching option is omitted.
| Env var | Option | Required? | Purpose |
|---|---|---|---|
MONOCLOUD_MANAGEMENT_DOMAIN | domain | yes | Bare tenant URL, e.g. https://acme.us.monocloud.com |
MONOCLOUD_MANAGEMENT_API_KEY | apiKey | yes | Management API key (sent as X-API-KEY) |
MONOCLOUD_MANAGEMENT_TIMEOUT | config.timeout | no | Per-request timeout in milliseconds (default 10000) |
The domain value should be the bare tenant URL — no /api, no trailing slash. The SDK sanitizes it (prepends https:// if missing, strips a trailing /, then appends /api/) and builds request paths itself.
Missing domain throws MonoCloudException (Tenant Domain is required); missing apiKey throws MonoCloudException (Api Key is required).
The env-var wiring for
MONOCLOUD_MANAGEMENT_TIMEOUTis finicky. For a reliable timeout, passconfig: { timeout }explicitly ininit()options rather than relying on the env var.
Quick start — env-driven
import { MonoCloudManagementClient } from "@monocloud/management";
// Reads MONOCLOUD_MANAGEMENT_DOMAIN and MONOCLOUD_MANAGEMENT_API_KEY from process.env.
const management = MonoCloudManagementClient.init();
const { result, status, pageData } = await management.users.getAllUsers(1, 25);
console.log(`Page ${pageData.current_page} of ${pageData.total_count} users`);
for (const user of result) console.log(user.user_id);
Quick start — explicit options
import { MonoCloudManagementClient } from "@monocloud/management";
const management = MonoCloudManagementClient.init({
domain: process.env.MONOCLOUD_MANAGEMENT_DOMAIN!,
apiKey: process.env.MONOCLOUD_MANAGEMENT_API_KEY!,
config: { timeout: 30_000 }, // optional, milliseconds
});
MonoCloudManagementClient.init(options?, fetcher?) is the only way to construct the client — the constructor is private, so new MonoCloudManagementClient() will not compile. Create one shared client at startup and reuse it. Never inline the API key as a string literal.
Client surface
MonoCloudManagementClient exposes ten read-only resource-client accessors — one per Management API area:
| Accessor | Client class | Resource area | Source file |
|---|---|---|---|
.branding | BrandingClient | Page / email / SMS branding options (read + patch) | clients/branding-api.ts |
.clients | ClientsClient | OAuth/OIDC applications, secrets, app↔group assignments (models named Application) | clients/clients-api.ts |
.groups | GroupsClient | Groups (RBAC / membership) | clients/groups-api.ts |
.keys | KeysClient | Signing key materials — list, rotate, revoke | clients/keys-api.ts |
.logs | LogsClient | Tenant audit / event logs | clients/logs-api.ts |
.networkZones | NetworkZonesClient | IP & regional network zones (ScaleX) | clients/network-zones-api.ts |
.options | OptionsClient | Tenant authentication & communication options, sign-up custom fields, external identity providers | clients/options-api.ts |
.resources | ResourcesClient | API resources, secrets, scopes, API access policies, standalone scopes, claim resources | clients/resources-api.ts |
.trustStores | TrustStoresClient | PKI & SPIFFE (mTLS) trust stores, revocations, banned certs/SVIDs | clients/trust-stores-api.ts |
.users | UsersClient | Full user lifecycle, identifiers, passwords, data, sessions, grants/tokens | clients/users-api.ts |
networkZones and trustStores accessors are camelCase. Each method returns Promise<MonoCloudResponse<T>>, or Promise<MonoCloudPageResponse<T>> for paginated getAll* lists.
See references/api-surface.md for the full method-by-method surface.
Response shape
Every call resolves to a MonoCloudResponse<T> (a class, not a plain object):
class MonoCloudResponse<T> {
result: T; // deserialized body — NOT `.data`
status: number;
headers: Record<string, any>;
}
// Returned by all paginated getAll* methods (extends MonoCloudResponse):
class MonoCloudPageResponse<T> extends MonoCloudResponse<T> {
pageData: {
page_size: number;
current_page: number;
total_count: number;
has_next: boolean;
has_previous: boolean;
};
}
pageData is parsed from the x-pagination response header. Empty / no-content responses (e.g. delete*) resolve to MonoCloudResponse<null> with result === null.
MonoCloudPageResponseand itsPageModelare exported from@monocloud/management-core, not from@monocloud/management. Don'timport { MonoCloudPageResponse } from "@monocloud/management"— it will beundefined. Rely on the method's inferred return type, or import from@monocloud/management-coreif you need the explicit annotation.
Pagination — idiomatic loop
Paginated list methods take (page?, size?, filter?, sort?). All four are optional and simply omitted from the query string when undefined (the server applies its own defaults), so pass page/size explicitly when you page.
async function* eachUser(management: MonoCloudManagementClient) {
let page = 1;
while (true) {
const { result, pageData } = await management.users.getAllUsers(page, 100);
for (const u of result) yield u;
if (!pageData.has_next) break;
page += 1;
}
}
page— 1-indexed.size— items per page.filter— filter expression (varies per endpoint; see the API reference).sort—"<field>:<1 | -1>"(1 = asc, -1 = desc).
A few list methods are non-paginated and return MonoCloudResponse<T[]> (no pageData): clients.getAllApplicationSecrets, resources.getAllApiResourceSecrets, options.getAllSignUpCustomFields, options.getAllExternalAuthenticators, trustStores.getAllPkiBannedCertificates, trustStores.getAllSpiffeBannedSvids.
Common operations
Create a user
const { result: user } = await management.users.createUser({
// shape defined by CreateUserRequest in the SDK types
email: "[email protected]",
name: "Alice Example",
});
Look up a user
import { MonoCloudNotFoundException } from "@monocloud/management";
try {
const { result: user } = await management.users.findUserById(userId);
return user;
} catch (e) {
if (e instanceof MonoCloudNotFoundException) return null;
throw e;
}
Patch user data and claims
await management.users.patchPrivateData(user.user_id, {
private_data: { onboarded: true, plan: "pro" },
});
await management.users.patchPublicData(user.user_id, {
public_data: { display_name: "Alice" },
});
All update methods are patch* (partial merge): keys you omit are left alone. There are no PUT / full-replace methods on the public surface.
List applications
const { result: apps, pageData } =
await management.clients.getAllApplications(1, 50);
The accessor is .clients, but its methods and models say Application: getAllApplications, createApplication, findApplicationById(clientId), patchApplication, deleteApplication. The path/id parameter is still clientId.
Read logs
const { result: logs, pageData } = await management.logs.getAllLogs(1, 50);
const { result: log } = await management.logs.findLogById(logId);
Assign a user to a group
const { result: membership } =
await management.users.assignUserToGroup(userId, groupId);
Errors
Every non-2xx response throws a typed exception. All extend MonoCloudException (which extends the native Error); every HTTP-error class extends MonoCloudRequestException.
| Class | Thrown for |
|---|---|
MonoCloudBadRequestException | 400 |
MonoCloudUnauthorizedException | 401 (bad / missing API key) |
MonoCloudPaymentRequiredException | 402 (feature needs a higher subscription tier — Pro / Secure+ / ScaleX) |
MonoCloudForbiddenException | 403 |
MonoCloudNotFoundException | 404 |
MonoCloudConflictException | 409 |
MonoCloudIdentityValidationException | 422 identity validation — has errors: IdentityError[] |
MonoCloudKeyValidationException | 422 key validation — has errors: Record<string, string[]> |
MonoCloudModelStateException | 422 (any other model-state / unprocessable-entity validation) |
MonoCloudResourceExhaustedException | 429 (rate limited) |
MonoCloudServerException | 500 |
MonoCloudRequestException | base for all HTTP-error classes — exposes response?: ProblemDetails |
MonoCloudException | base class — also thrown for missing config, timeouts, and unmapped status codes |
MonoCloudException has no statusCode property. Branch on status with instanceof against a subclass, and read the server problem-details body via (e as MonoCloudRequestException).response?.status / .title / .detail. Timeouts surface as a plain MonoCloudException (the underlying error's name === 'TimeoutError'), not a dedicated class.
import {
MonoCloudConflictException,
MonoCloudIdentityValidationException,
MonoCloudPaymentRequiredException,
MonoCloudRequestException,
} from "@monocloud/management";
try {
await management.users.createUser(body);
} catch (e) {
if (e instanceof MonoCloudConflictException) return { code: 409, error: "duplicate" };
if (e instanceof MonoCloudIdentityValidationException) return { code: 422, errors: e.errors };
if (e instanceof MonoCloudPaymentRequiredException) return { code: 402, error: "upgrade required" };
if (e instanceof MonoCloudRequestException) {
console.error("Management API call failed", e.response?.status, e.response);
}
throw e;
}
Subscription tiers (402 gating)
Some methods and request/option fields require a higher tenant subscription and return 402 → MonoCloudPaymentRequiredException otherwise. Verify the tenant's plan before wiring these into production.
| Tier | Gated methods (examples) |
|---|---|
| ScaleX | clients.assignGroupToApplication / removeGroupFromApplication; all networkZones create/patch; resources.createApiResourceSecret |
| Pro | groups.createGroup (beyond 2 groups); users.getAllUserSessions / findUserSession / revokeUserSession; users.getAllUserClientGrants |
| Secure+ | users.getAllUserConsents / getAllReferenceTokens / getAllRefreshTokens / getAllAuthorizationCodes and the matching revoke* methods |
Field-level gates also exist (e.g. application consent fields need Secure+; generating API secrets and reference tokens need ScaleX). See references/api-surface.md for the per-method annotations.
Replacing the HTTP layer (optional)
MonoCloudManagementClient.init(options?, fetcher?) accepts a second argument of type Fetcher:
type Fetcher = (input: string | URL, init?: RequestInit) => Promise<Response>;
When you supply a fetcher, it fully replaces the built-in pipeline — the SDK will no longer add the base URL (/api/), the X-API-KEY / Content-Type headers, or the timeout AbortSignal. Your fetcher must handle base-URL resolution, auth headers, and timeouts itself. Use it for custom transports, retries, logging, proxies, or non-standard runtimes; for ordinary code prefer the built-in fetcher and set config.timeout.
(This is the JS/TS SDK — there is no DI container registration here. AddMonoCloudManagementClient belongs to the .NET SDK; see monocloud-management-dotnet.)
Common pitfalls
new MonoCloudManagementClient(). The constructor is private — always use the staticMonoCloudManagementClient.init(...).- Reading
.data. The JS SDK puts the body on.result;.data/.PageDataare the .NET SDK's names. - Putting the API key in browser code. Management keys are full-tenant admin and must run server-side only.
- Trailing
/apiondomain. Pass the bare tenant URL — the SDK appends/api/itself; duplicating it yields 404s. - Importing
MonoCloudPageResponse/PageModel/ProblemDetailsfrom@monocloud/management. They aren't re-exported there — rely on inferred return types or import from@monocloud/management-core. clients.getAllClients()/logs.getLogs(). Real names areclients.getAllApplications(...)andlogs.getAllLogs(...). The.clientsaccessor exists, but its methods and models sayApplication.- Transposing ResourcesClient id params.
findApiResourceSecretById(secretId, apiId),findApiScopeById(scopeId, apiId),patchApiScope(scopeId, apiId, body), anddeleteApiScope(scopeId, apiId)take the child id first, whereascreateApiResourceSecret(apiId, body),deleteApiResourceSecret(apiId, secretId),getAllApiScopes(apiId, ...), andcreateApiScope(apiId, body)takeapiIdfirst. Easy to reverse. - Treating
patch*as full replace. Patches merge; omitted fields are untouched. Identifier fields (e.g. an API resource'saudience, a scope'sname) are absent from thePatch*Requesttypes by design and cannot be changed — TypeScript flags them at the call site. - Catching
Errorinstead ofMonoCloudException. The typed hierarchy lets you branch on 404 vs 409 vs 422 without string-matching. - Reading
e.statusCode. It doesn't exist. Useinstanceofor(e as MonoCloudRequestException).response?.status. - Forgetting pagination.
getAll*returns one page. Loop onpageData.has_next. - Timeout units.
config.timeoutis milliseconds (default10000), not seconds. - Narrowing discriminated unions.
INetworkZoneandICertificateRevocationare unions — narrow on thetypefield ('ip'/'regional','base'/'delta') before touching subtype fields.
Onboarding checklist
npm install @monocloud/management.- Create a Management API key in the MonoCloud dashboard.
- Set
MONOCLOUD_MANAGEMENT_DOMAINandMONOCLOUD_MANAGEMENT_API_KEYin a server-only,.gitignored env file. import { MonoCloudManagementClient } from '@monocloud/management'; create one shared client withinit()and reuse it.- Read results from
.result(and.pageDatafor lists); wrap calls intry/catchagainst the specificMonoCloudExceptionsubclasses you expect. - Run
node skills/monocloud-management-js/scripts/verify.jsto confirm env + dependency wiring.
Deeper reference
references/api-surface.md— resource-by-resource method index, parameter orders, subscription-tier annotations, and model names.references/troubleshooting.md— symptom → cause → fix index for the common failure modes (401 / 402 / 403, domain/apiduplication, browser-side key leaks,patch*merge semantics,catch (Error), single-page reads, millisecond timeouts).