โ† Back to list
groeimetai

scoped-apps

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.

โญ 42๐Ÿด 9๐Ÿ“… Jan 23, 2026

SKILL.md


name: scoped-apps description: This skill should be used when the user asks to "create application", "scoped application", "custom app", "application scope", "x_" prefix, "app scope", "application properties", "cross-scope", or any ServiceNow scoped application development. license: Apache-2.0 compatibility: Designed for Snow-Code and ServiceNow development metadata: author: groeimetai version: "1.0.0" category: servicenow tools:

  • snow_create_scoped_application
  • snow_update_set_create
  • snow_query_table
  • snow_property_manager

Scoped Application Development for ServiceNow

Scoped applications provide isolation and portability for custom development in ServiceNow.

Why Use Scoped Apps?

FeatureGlobal ScopeScoped App
Naming conflictsPossiblePrevented (x_prefix)
PortabilityDifficultEasy (Update Sets)
SecurityOpenControlled (Cross-scope)
Store publishingNoYes
DependenciesImplicitExplicit

Creating a Scoped Application

1. Navigate: System Applications > Studio
2. Click: Create Application
3. Enter:
   - Name: "My Custom App"
   - Scope: "x_mycom_myapp" (auto-generated)
   - Version: 1.0.0
4. Configure:
   - Runtime access: Check tables needing cross-scope access

Via MCP

snow_create_application({
  name: "My Custom Application",
  scope: "x_mycom_custom",
  version: "1.0.0",
  description: "Custom application for..."
});

Scope Naming Convention

x_[vendor]_[app]

Examples:
- x_acme_hr          (ACME Corp HR App)
- x_mycom_inventory  (My Company Inventory)
- x_snc_global       (ServiceNow Global)

Table Naming

// Scoped tables are automatically prefixed
// Table name in Studio: "task_tracker"
// Actual table name: "x_mycom_myapp_task_tracker"

// Creating records
var gr = new GlideRecord('x_mycom_myapp_task_tracker');
gr.initialize();
gr.setValue('name', 'My Task');
gr.insert();

Script Include in Scoped App

var TaskManager = Class.create();
TaskManager.prototype = {
  initialize: function() {
    this.tableName = 'x_mycom_myapp_task_tracker';
  },

  createTask: function(name, description) {
    var gr = new GlideRecord(this.tableName);
    gr.initialize();
    gr.setValue('name', name);
    gr.setValue('description', description);
    return gr.insert();
  },

  // Mark as accessible from other scopes
  // Requires: "Accessible from: All application scopes"
  getTask: function(sysId) {
    var gr = new GlideRecord(this.tableName);
    if (gr.get(sysId)) {
      return {
        name: gr.getValue('name'),
        description: gr.getValue('description')
      };
    }
    return null;
  },

  type: 'TaskManager'
};

Cross-Scope Access

Calling Other Scope's Script Include

// From scope: x_mycom_otherapp
// Calling: x_mycom_myapp.TaskManager

// Option 1: Direct call (if accessible)
var tm = new x_mycom_myapp.TaskManager();
var task = tm.getTask(sysId);

// Option 2: GlideScopedEvaluator
var evaluator = new GlideScopedEvaluator();
evaluator.putVariable('sysId', sysId);
var result = evaluator.evaluateScript(
  'x_mycom_myapp',
  'new TaskManager().getTask(sysId)'
);

Accessing Other Scope's Tables

// Check if cross-scope access is allowed
var gr = new GlideRecord('x_other_app_table');
if (!gr.isValid()) {
  gs.error('No access to x_other_app_table');
  return;
}

// If accessible, query normally
gr.addQuery('active', true);
gr.query();

Application Properties

Define Properties

// In Application > Properties
// Name: x_mycom_myapp.default_priority
// Value: 3
// Type: string

// In Application > Modules
// Create "Properties" module pointing to:
// /sys_properties_list.do?sysparm_query=name=x_mycom_myapp

Use Properties

// Get property value
var defaultPriority = gs.getProperty('x_mycom_myapp.default_priority', '3');

// Set property value (requires admin)
gs.setProperty('x_mycom_myapp.default_priority', '2');

Application Files Structure

x_mycom_myapp/
โ”œโ”€โ”€ Tables
โ”‚   โ”œโ”€โ”€ x_mycom_myapp_task
โ”‚   โ””โ”€โ”€ x_mycom_myapp_config
โ”œโ”€โ”€ Script Includes
โ”‚   โ”œโ”€โ”€ TaskManager
โ”‚   โ””โ”€โ”€ ConfigUtils
โ”œโ”€โ”€ Business Rules
โ”‚   โ””โ”€โ”€ Validate Task
โ”œโ”€โ”€ UI Pages
โ”‚   โ””โ”€โ”€ task_dashboard
โ”œโ”€โ”€ REST API
โ”‚   โ””โ”€โ”€ Task API
โ”œโ”€โ”€ Scheduled Jobs
โ”‚   โ””โ”€โ”€ Daily Cleanup
โ””โ”€โ”€ Application Properties
    โ”œโ”€โ”€ default_priority
    โ””โ”€โ”€ enable_notifications

REST API in Scoped App

Define Scripted REST API

// Resource: /api/x_mycom_myapp/tasks
// HTTP Method: GET

(function process(request, response) {
  var tasks = [];
  var gr = new GlideRecord('x_mycom_myapp_task_tracker');
  gr.addQuery('active', true);
  gr.query();

  while (gr.next()) {
    tasks.push({
      sys_id: gr.getUniqueValue(),
      name: gr.getValue('name'),
      status: gr.getValue('status')
    });
  }

  response.setBody({
    result: tasks,
    count: tasks.length
  });

})(request, response);

Calling the API

curl -X GET \
  "https://instance.service-now.com/api/x_mycom_myapp/tasks" \
  -H "Authorization: Bearer token"

Application Dependencies

Declare Dependencies

Application > Dependencies
Add:
  - sn_hr_core (HR Core)
  - sn_cmdb (CMDB)

Check Dependencies in Code

// Check if plugin is active
if (GlidePluginManager.isActive('com.snc.hr.core')) {
  // HR Core is available
  var hrCase = new sn_hr_core.hr_case();
}

Publishing to Store

Checklist Before Publishing

โ–ก All tables have proper ACLs
โ–ก No hard-coded sys_ids
โ–ก No hard-coded instance URLs
โ–ก All dependencies declared
โ–ก Properties have default values
โ–ก Documentation complete
โ–ก Test cases pass
โ–ก No global scope modifications
โ–ก Update Set tested on clean instance

Version Management

Major.Minor.Patch
1.0.0 - Initial release
1.1.0 - New feature added
1.1.1 - Bug fix
2.0.0 - Breaking change

Common Mistakes

MistakeProblemSolution
Global modificationsWon't deploy cleanlyKeep changes in scope
Hard-coded sys_idsFails on other instancesUse properties or lookups
Missing ACLsSecurity vulnerabilitiesCreate ACLs for all tables
No error handlingSilent failuresAdd try/catch, logging
Accessing global tables directlyUpgrade conflictsUse references, not copies

Best Practices

  1. Single Responsibility - One app per business function
  2. Explicit Dependencies - Declare all requirements
  3. Property-Driven - Configurable without code changes
  4. Defensive Coding - Check access before operations
  5. Documentation - Include README, release notes
  6. Testing - Automated tests for critical functions
  7. Versioning - Semantic versioning for updates

Score

Total Score

75/100

Based on repository quality metrics

โœ“SKILL.md

SKILL.mdใƒ•ใ‚กใ‚คใƒซใŒๅซใพใ‚Œใฆใ„ใ‚‹

+20
โœ“LICENSE

ใƒฉใ‚คใ‚ปใƒณใ‚นใŒ่จญๅฎšใ•ใ‚Œใฆใ„ใ‚‹

+10
โœ“่ชฌๆ˜Žๆ–‡

100ๆ–‡ๅญ—ไปฅไธŠใฎ่ชฌๆ˜ŽใŒใ‚ใ‚‹

+10
โ—‹ไบบๆฐ—

GitHub Stars 100ไปฅไธŠ

0/15
โœ“ๆœ€่ฟ‘ใฎๆดปๅ‹•

1ใƒถๆœˆไปฅๅ†…ใซๆ›ดๆ–ฐ

+10
โ—‹ใƒ•ใ‚ฉใƒผใ‚ฏ

10ๅ›žไปฅไธŠใƒ•ใ‚ฉใƒผใ‚ฏใ•ใ‚Œใฆใ„ใ‚‹

0/5
โœ“Issue็ฎก็†

ใ‚ชใƒผใƒ—ใƒณIssueใŒ50ๆœชๆบ€

+5
โœ“่จ€่ชž

ใƒ—ใƒญใ‚ฐใƒฉใƒŸใƒณใ‚ฐ่จ€่ชžใŒ่จญๅฎšใ•ใ‚Œใฆใ„ใ‚‹

+5
โœ“ใ‚ฟใ‚ฐ

1ใคไปฅไธŠใฎใ‚ฟใ‚ฐใŒ่จญๅฎšใ•ใ‚Œใฆใ„ใ‚‹

+5

Reviews

๐Ÿ’ฌ

Reviews coming soon