
cmdb-patterns
by groeimetai
๐ค AI-powered ServiceNow development with 400+ MCP tools. Works with Claude, GPT, Gemini, Ollama & 75+ providers. Deploy widgets, manage incidents, automate workflows - all through natural language. Open-source Build Agent alternative.
SKILL.md
name: cmdb-patterns description: This skill should be used when the user asks to "create CI", "CMDB", "configuration item", "CI relationship", "impact analysis", "dependency map", "cmdb_ci", "asset", or any ServiceNow CMDB and configuration management development. license: Apache-2.0 compatibility: Designed for Snow-Code and ServiceNow development metadata: author: groeimetai version: "1.0.0" category: servicenow tools:
- snow_cmdb_search
- snow_cmdb_ci_create
- snow_cmdb_relationship_create
- snow_query_table
CMDB Patterns for ServiceNow
The Configuration Management Database (CMDB) is the foundation of ServiceNow ITSM, tracking all Configuration Items (CIs) and their relationships.
CMDB Architecture
CI Class Hierarchy
cmdb (Base)
โโโ cmdb_ci (Configuration Item)
โโโ cmdb_ci_computer
โ โโโ cmdb_ci_server
โ โ โโโ cmdb_ci_linux_server
โ โ โโโ cmdb_ci_win_server
โ โ โโโ cmdb_ci_unix_server
โ โโโ cmdb_ci_pc_hardware
โโโ cmdb_ci_service
โ โโโ cmdb_ci_service_auto
โ โโโ cmdb_ci_service_discovered
โโโ cmdb_ci_appl
โ โโโ cmdb_ci_app_server
โ โโโ cmdb_ci_db_instance
โโโ cmdb_ci_network_gear
โโโ cmdb_ci_netgear
โโโ cmdb_ci_lb
Key CI Tables
| Table | Purpose | Key Fields |
|---|---|---|
cmdb_ci | Base CI table | name, sys_class_name, operational_status |
cmdb_ci_server | Servers | ip_address, os, cpu_count, ram |
cmdb_ci_service | Business Services | service_classification, busines_criticality |
cmdb_ci_appl | Applications | version, install_directory |
cmdb_rel_ci | CI Relationships | parent, child, type |
Creating Configuration Items
Basic CI Creation (ES5)
// Create a new server CI
var ci = new GlideRecord('cmdb_ci_server');
ci.initialize();
ci.setValue('name', 'PROD-WEB-001');
ci.setValue('ip_address', '10.0.1.100');
ci.setValue('os', 'Linux Red Hat');
ci.setValue('os_version', '8.5');
ci.setValue('cpu_count', 8);
ci.setValue('ram', 32768);
ci.setValue('operational_status', 1); // Operational
ci.setValue('install_status', 1); // Installed
ci.setValue('used_for', 'Production');
ci.setValue('owned_by', 'sys_id_of_owner');
ci.setValue('support_group', 'sys_id_of_group');
var sysId = ci.insert();
CI with Discovery Source
// CI from Discovery
var ci = new GlideRecord('cmdb_ci_linux_server');
ci.initialize();
ci.setValue('name', 'discovered-server-001');
ci.setValue('discovery_source', 'ServiceNow');
ci.setValue('first_discovered', new GlideDateTime());
ci.setValue('last_discovered', new GlideDateTime());
ci.setValue('ip_address', '10.0.2.50');
// Set classification
ci.setValue('classification', 'Production');
ci.setValue('environment', 'Production');
ci.insert();
CI Relationships
Relationship Types
| Type | Parent โ Child | Example |
|---|---|---|
Runs on::Runs | App โ Server | ERP runs on PROD-DB-01 |
Depends on::Used by | Service โ App | HR Service depends on SAP |
Contains::Contained by | Cluster โ Server | Cluster contains Node1 |
Hosted on::Hosts | VM โ Hypervisor | VM01 hosted on ESX01 |
Members::Member of | CI โ Group | Server member of Pool |
Creating Relationships (ES5)
// Create relationship between CIs
function createCIRelationship(parentSysId, childSysId, relationType) {
// Find relationship type
var relType = new GlideRecord('cmdb_rel_type');
relType.addQuery('name', relationType);
relType.query();
if (!relType.next()) {
gs.error('Relationship type not found: ' + relationType);
return null;
}
// Check if relationship already exists
var existing = new GlideRecord('cmdb_rel_ci');
existing.addQuery('parent', parentSysId);
existing.addQuery('child', childSysId);
existing.addQuery('type', relType.getUniqueValue());
existing.query();
if (existing.next()) {
gs.info('Relationship already exists');
return existing.getUniqueValue();
}
// Create new relationship
var rel = new GlideRecord('cmdb_rel_ci');
rel.initialize();
rel.setValue('parent', parentSysId);
rel.setValue('child', childSysId);
rel.setValue('type', relType.getUniqueValue());
return rel.insert();
}
// Usage
createCIRelationship(appSysId, serverSysId, 'Runs on::Runs');
Querying Relationships
// Find all servers an application runs on
function getAppServers(appSysId) {
var servers = [];
var rel = new GlideRecord('cmdb_rel_ci');
rel.addQuery('parent', appSysId);
rel.addQuery('type.name', 'Runs on::Runs');
rel.query();
while (rel.next()) {
var server = rel.child.getRefRecord();
servers.push({
sys_id: server.getUniqueValue(),
name: server.getValue('name'),
ip_address: server.getValue('ip_address')
});
}
return servers;
}
// Find all dependencies of a service
function getServiceDependencies(serviceSysId) {
var deps = [];
var rel = new GlideRecord('cmdb_rel_ci');
rel.addQuery('parent', serviceSysId);
rel.addQuery('type.name', 'Depends on::Used by');
rel.query();
while (rel.next()) {
deps.push({
sys_id: rel.child.getUniqueValue(),
name: rel.child.getDisplayValue(),
class: rel.child.sys_class_name.toString()
});
}
return deps;
}
Impact Analysis
Upstream/Downstream Analysis
// Get all CIs affected by a CI outage (downstream impact)
function getDownstreamImpact(ciSysId, depth) {
if (typeof depth === 'undefined') depth = 3;
var impacted = [];
var processed = {};
function traverse(sysId, currentDepth) {
if (currentDepth > depth || processed[sysId]) return;
processed[sysId] = true;
var rel = new GlideRecord('cmdb_rel_ci');
rel.addQuery('child', sysId);
rel.query();
while (rel.next()) {
var parentId = rel.parent.toString();
if (!processed[parentId]) {
impacted.push({
sys_id: parentId,
name: rel.parent.getDisplayValue(),
depth: currentDepth
});
traverse(parentId, currentDepth + 1);
}
}
}
traverse(ciSysId, 1);
return impacted;
}
// Get all CIs this CI depends on (upstream dependencies)
function getUpstreamDependencies(ciSysId, depth) {
if (typeof depth === 'undefined') depth = 3;
var dependencies = [];
var processed = {};
function traverse(sysId, currentDepth) {
if (currentDepth > depth || processed[sysId]) return;
processed[sysId] = true;
var rel = new GlideRecord('cmdb_rel_ci');
rel.addQuery('parent', sysId);
rel.query();
while (rel.next()) {
var childId = rel.child.toString();
if (!processed[childId]) {
dependencies.push({
sys_id: childId,
name: rel.child.getDisplayValue(),
depth: currentDepth
});
traverse(childId, currentDepth + 1);
}
}
}
traverse(ciSysId, 1);
return dependencies;
}
Business Service Impact
// Find all business services impacted by a CI
function getImpactedServices(ciSysId) {
var services = [];
var processed = {};
function findServices(sysId) {
if (processed[sysId]) return;
processed[sysId] = true;
// Check if this CI is a service
var ci = new GlideRecord('cmdb_ci');
if (ci.get(sysId)) {
if (ci.sys_class_name.toString().indexOf('cmdb_ci_service') === 0) {
services.push({
sys_id: sysId,
name: ci.getValue('name'),
criticality: ci.getValue('busines_criticality')
});
}
}
// Traverse upstream
var rel = new GlideRecord('cmdb_rel_ci');
rel.addQuery('child', sysId);
rel.query();
while (rel.next()) {
findServices(rel.parent.toString());
}
}
findServices(ciSysId);
return services;
}
CMDB Health & Data Quality
Orphan CI Detection
// Find CIs without relationships
function findOrphanCIs(ciClass) {
var orphans = [];
var ci = new GlideRecord(ciClass || 'cmdb_ci');
ci.addQuery('operational_status', 1); // Operational only
ci.query();
while (ci.next()) {
var sysId = ci.getUniqueValue();
// Check for any relationships
var rel = new GlideRecord('cmdb_rel_ci');
rel.addQuery('parent', sysId)
.addOrCondition('child', sysId);
rel.setLimit(1);
rel.query();
if (!rel.hasNext()) {
orphans.push({
sys_id: sysId,
name: ci.getValue('name'),
class: ci.getValue('sys_class_name')
});
}
}
return orphans;
}
Stale CI Detection
// Find CIs not updated by discovery
function findStaleCIs(daysOld) {
if (typeof daysOld === 'undefined') daysOld = 30;
var stale = [];
var cutoff = new GlideDateTime();
cutoff.addDaysLocalTime(-daysOld);
var ci = new GlideRecord('cmdb_ci');
ci.addQuery('operational_status', 1);
ci.addQuery('last_discovered', '<', cutoff);
ci.addNotNullQuery('last_discovered');
ci.query();
while (ci.next()) {
stale.push({
sys_id: ci.getUniqueValue(),
name: ci.getValue('name'),
last_discovered: ci.getValue('last_discovered')
});
}
return stale;
}
MCP Tool Integration
Available CMDB Tools
| Tool | Purpose |
|---|---|
snow_create_ci | Create new CI with proper class |
snow_cmdb_search | Search CIs with filters |
snow_create_ci_relationship | Create CI relationships |
snow_impact_analysis | Analyze CI impact |
snow_get_ci_details | Get full CI information |
snow_run_discovery | Trigger discovery |
Example Workflow
// 1. Search for existing CI
await snow_cmdb_search({
ci_class: 'cmdb_ci_server',
query: 'name=PROD-WEB-001',
include_relationships: true
});
// 2. Create new CI if not found
await snow_create_ci({
ci_class: 'cmdb_ci_linux_server',
name: 'PROD-WEB-002',
ip_address: '10.0.1.101',
operational_status: 1
});
// 3. Create relationship
await snow_create_ci_relationship({
parent: appSysId,
child: serverSysId,
type: 'Runs on::Runs'
});
// 4. Impact analysis
await snow_impact_analysis({
ci_sys_id: serverSysId,
direction: 'downstream',
depth: 3
});
Best Practices
- Use Correct CI Class - Always use most specific class (cmdb_ci_linux_server, not cmdb_ci)
- Maintain Relationships - CIs without relationships have limited value
- Discovery Alignment - Align manual CIs with discovery patterns
- Operational Status - Keep status current (Operational, Retired, etc.)
- Unique Identifiers - Use serial_number, asset_tag for uniqueness
- Service Mapping - Connect CIs to business services
- Regular Cleanup - Archive retired CIs, remove orphans
Score
Total Score
Based on repository quality metrics
SKILL.mdใใกใคใซใๅซใพใใฆใใ
ใฉใคใปใณในใ่จญๅฎใใใฆใใ
100ๆๅญไปฅไธใฎ่ชฌๆใใใ
GitHub Stars 100ไปฅไธ
1ใถๆไปฅๅ ใซๆดๆฐ
10ๅไปฅไธใใฉใผใฏใใใฆใใ
ใชใผใใณIssueใ50ๆชๆบ
ใใญใฐใฉใใณใฐ่จ่ชใ่จญๅฎใใใฆใใ
1ใคไปฅไธใฎใฟใฐใ่จญๅฎใใใฆใใ
Reviews
Reviews coming soon


