{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/stormmcp/json-schema/stormmcp-dynamic-gateway-inventory-response-schema.json",
  "title": "DynamicGatewayInventoryResponse",
  "description": "The MCP Gateway Inventory read of one user's Dynamic Gateway (MCPG-1881): stored configuration\nonly. It carries toolkits with their enabled state, per-toolkit app membership, per-tool\nmembership and enabled state, and the Radar cache. It never carries credential material,\nconnection state, or a per-connection identifier — `DynamicGatewayInventoryContractTests`\npins the whole graph, so adding a property here means updating that allowlist under review.",
  "x-generated": "2026-11-10",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/stormmcp-mcpgatewayinventory-api-openapi.yml#/components/schemas/DynamicGatewayInventoryResponse",
  "type": "object",
  "properties": {
    "tenantId": {
      "type": "string",
      "description": "Gets or sets the tenant the read was scoped to (always the caller's tenant).",
      "format": "uuid"
    },
    "userId": {
      "type": "string",
      "description": "Gets or sets the subject user whose Dynamic Gateway this is.",
      "format": "uuid"
    },
    "groupMembershipDegraded": {
      "type": "boolean",
      "description": "Gets or sets a value indicating whether the subject's group membership could not be\nresolved, in which case IReadOnlyList&lt;DynamicGatewayInventoryAssignedToolkitResponse&gt; DynamicGatewayInventoryResponse.AssignedToolkits holds direct assignments only and\nmay be incomplete."
    },
    "toolkits": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/DynamicGatewayInventoryToolkitResponse"
      },
      "description": "Gets or sets the subject's own toolkits."
    },
    "assignedToolkits": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/DynamicGatewayInventoryAssignedToolkitResponse"
      },
      "description": "Gets or sets the admin toolkits assigned to the subject, directly or through a group."
    },
    "apps": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/DynamicGatewayInventoryAppResponse"
      },
      "description": "Gets or sets the subject's app-level preferences (one row per library the subject has a\nstored preference for)."
    },
    "skills": {
      "oneOf": [
        {
          "type": "null"
        },
        {
          "description": "Gets or sets the subject's Skills toolkit preference, or null when the subject has never\ntouched it.",
          "$ref": "#/$defs/DynamicGatewayInventorySkillsResponse"
        }
      ]
    },
    "radarCache": {
      "description": "Gets or sets the subject's Radar cache.",
      "$ref": "#/$defs/DynamicGatewayInventoryRadarCacheResponse"
    }
  },
  "$defs": {
    "AdminToolkitAssignmentMode": {
      "description": "How assignees may change an admin-assigned toolkit (MCPG-1699).\nExisting rows default to AdminToolkitAssignmentMode.Editable."
    },
    "DynamicGatewayInventoryAppResponse": {
      "type": "object",
      "properties": {
        "libraryId": {
          "type": "string",
          "description": "Gets or sets the library identifier.",
          "format": "uuid"
        },
        "name": {
          "type": [
            "null",
            "string"
          ],
          "description": "Gets or sets the app display name, or null when the library is no longer on the tenant's list."
        },
        "iconUrl": {
          "type": [
            "null",
            "string"
          ],
          "description": "Gets or sets the app icon URL."
        },
        "type": {
          "oneOf": [
            {
              "type": "null"
            },
            {
              "description": "Gets or sets the server type.",
              "$ref": "#/$defs/McpServerType"
            }
          ]
        },
        "enabledOverride": {
          "type": [
            "null",
            "boolean"
          ],
          "description": "Gets or sets the subject's explicit enable/disable override; null means the admin default applies."
        },
        "toolMode": {
          "description": "Gets or sets the tool selection mode.",
          "$ref": "#/$defs/DynamicToolPreferenceMode"
        },
        "tools": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/DynamicGatewayInventoryToolResponse"
          },
          "description": "Gets or sets the tools known for this app with their enabled state."
        }
      },
      "description": "The subject's app-level preference for one library."
    },
    "DynamicGatewayInventoryAssignedToolkitResponse": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Gets or sets the admin toolkit identifier.",
          "format": "uuid"
        },
        "name": {
          "type": "string",
          "description": "Gets or sets the toolkit name."
        },
        "description": {
          "type": [
            "null",
            "string"
          ],
          "description": "Gets or sets the optional description."
        },
        "assignmentMode": {
          "description": "Gets or sets the assignment mode (MCPG-1699).",
          "$ref": "#/$defs/AdminToolkitAssignmentMode"
        },
        "hidden": {
          "type": "boolean",
          "description": "Gets or sets a value indicating whether the subject has hidden this toolkit."
        },
        "members": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/DynamicGatewayInventoryToolkitMemberResponse"
          },
          "description": "Gets or sets the toolkit members."
        }
      },
      "description": "An admin toolkit assigned to the subject."
    },
    "DynamicGatewayInventoryRadarCacheEntryResponse": {
      "type": "object",
      "properties": {
        "toolName": {
          "type": "string",
          "description": "Gets or sets the cached wire name (`{prefix}__{tool}` on the Dynamic surface)."
        },
        "serverName": {
          "type": [
            "null",
            "string"
          ],
          "description": "Gets or sets the owning app's display name from the tenant list, or null when unresolvable."
        },
        "libraryId": {
          "type": [
            "null",
            "string"
          ],
          "description": "Gets or sets the owning library identifier, or null when unresolvable.",
          "format": "uuid"
        },
        "iconUrl": {
          "type": [
            "null",
            "string"
          ],
          "description": "Gets or sets the owning app's icon URL."
        },
        "pinned": {
          "type": "boolean",
          "description": "Gets or sets a value indicating whether the entry is pinned."
        },
        "useCount": {
          "pattern": "^-?(?:0|[1-9]\\d*)$",
          "type": [
            "integer",
            "string"
          ],
          "description": "Gets or sets the cache's all-time use count for the entry.",
          "format": "int64"
        },
        "lastUsedAt": {
          "type": "string",
          "description": "Gets or sets when the entry was last used.",
          "format": "date-time"
        }
      },
      "description": "One Radar cache entry."
    },
    "DynamicGatewayInventoryRadarCacheResponse": {
      "type": "object",
      "properties": {
        "size": {
          "pattern": "^-?(?:0|[1-9]\\d*)$",
          "type": [
            "integer",
            "string"
          ],
          "description": "Gets or sets the configured cache size (the subject's override, else the tenant default).",
          "format": "int32"
        },
        "entries": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/DynamicGatewayInventoryRadarCacheEntryResponse"
          },
          "description": "Gets or sets the cached entries."
        }
      },
      "description": "The subject's Radar cache."
    },
    "DynamicGatewayInventorySkillSourceResponse": {
      "type": "object",
      "properties": {
        "libraryId": {
          "type": "string",
          "description": "Gets or sets the library identifier.",
          "format": "uuid"
        },
        "name": {
          "type": [
            "null",
            "string"
          ],
          "description": "Gets or sets the source display name."
        },
        "enabled": {
          "type": "boolean",
          "description": "Gets or sets a value indicating whether the subject has opted this source in. Stored state\nonly: it is independent of the master switch, which bool DynamicGatewayInventorySkillsResponse.Enabled\ncarries, so a master-off subject's opt-ins stay readable."
        }
      },
      "description": "One skill source (a SkillLink server) and whether the subject serves it."
    },
    "DynamicGatewayInventorySkillsResponse": {
      "type": "object",
      "properties": {
        "enabled": {
          "type": "boolean",
          "description": "Gets or sets a value indicating whether the Skills master switch is on."
        },
        "sources": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/DynamicGatewayInventorySkillSourceResponse"
          },
          "description": "Gets or sets the tenant's skill sources with the subject's opt-in state."
        }
      },
      "description": "The subject's Skills toolkit preference (MCPG-1511 / MCPG-1766): the master switch and the\nper-source opt-in, each as stored. Per-skill deselections are deliberately out of scope for\nMCPG-1881; adding them is a reviewed change to the pinned contract."
    },
    "DynamicGatewayInventoryToolResponse": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "Gets or sets the upstream tool name."
        },
        "enabled": {
          "type": "boolean",
          "description": "Gets or sets a value indicating whether the tool is enabled under the stored selection."
        }
      },
      "description": "One tool row. The set is the union of the stored selection and the tools the subject's Radar\ncache has discovered for that app — the only inventory knowable without the subject's\ncredentials (PRD D2). `All`-mode rows are therefore the discovered set, all enabled."
    },
    "DynamicGatewayInventoryToolkitMemberResponse": {
      "type": "object",
      "properties": {
        "libraryId": {
          "type": "string",
          "description": "Gets or sets the library identifier.",
          "format": "uuid"
        },
        "name": {
          "type": [
            "null",
            "string"
          ],
          "description": "Gets or sets the app display name, or null when the library is no longer on the tenant's list."
        },
        "iconUrl": {
          "type": [
            "null",
            "string"
          ],
          "description": "Gets or sets the app icon URL."
        },
        "type": {
          "oneOf": [
            {
              "type": "null"
            },
            {
              "description": "Gets or sets the server type.",
              "$ref": "#/$defs/McpServerType"
            }
          ]
        },
        "toolMode": {
          "description": "Gets or sets the tool selection mode for this membership.",
          "$ref": "#/$defs/DynamicToolPreferenceMode"
        },
        "tools": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/DynamicGatewayInventoryToolResponse"
          },
          "description": "Gets or sets the tools known for this app with their enabled state. See\nDynamicGatewayInventoryToolResponse for what \"known\" means."
        }
      },
      "description": "One app inside a toolkit, with its per-tool membership and enabled state."
    },
    "DynamicGatewayInventoryToolkitResponse": {
      "type": "object",
      "properties": {
        "id": {
          "type": "string",
          "description": "Gets or sets the toolkit identifier.",
          "format": "uuid"
        },
        "name": {
          "type": "string",
          "description": "Gets or sets the toolkit name."
        },
        "description": {
          "type": [
            "null",
            "string"
          ],
          "description": "Gets or sets the optional description."
        },
        "enabled": {
          "type": "boolean",
          "description": "Gets or sets a value indicating whether the toolkit master switch is on."
        },
        "members": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/DynamicGatewayInventoryToolkitMemberResponse"
          },
          "description": "Gets or sets the toolkit members in the owner's sort order."
        },
        "createdAt": {
          "type": "string",
          "description": "Gets or sets the creation timestamp.",
          "format": "date-time"
        },
        "updatedAt": {
          "type": "string",
          "description": "Gets or sets the update timestamp.",
          "format": "date-time"
        }
      },
      "description": "One of the subject's own toolkits."
    },
    "DynamicToolPreferenceMode": {
      "type": "integer",
      "description": "Specifies how a user's dynamic gateway should expose upstream tools for a library."
    },
    "McpServerType": {
      "type": "integer",
      "description": "An mcp server type enumeration."
    }
  }
}