snow-flow 8.37.27 โ 8.38.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.snow-code/agent/deployment-specialist.md +346 -0
- package/.snow-code/agent/orchestrator.md +286 -0
- package/.snow-code/agent/risk-assessor.md +454 -0
- package/.snow-code/agent/solution-architect.md +582 -0
- package/.snow-code/agent/validator.md +503 -0
- package/.snow-code/opencode.json +49 -0
- package/README.md +16 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +104 -266
- package/dist/cli.js.map +1 -1
- package/dist/utils/config-cache.js +6 -6
- package/dist/utils/config-cache.js.map +1 -1
- package/dist/utils/sync-mcp-configs.d.ts +7 -5
- package/dist/utils/sync-mcp-configs.d.ts.map +1 -1
- package/dist/utils/sync-mcp-configs.js +19 -74
- package/dist/utils/sync-mcp-configs.js.map +1 -1
- package/package.json +2 -3
- package/scripts/check-binary-updates.js +0 -169
- package/scripts/check-npm-version.js +0 -92
- package/scripts/classify-all-tools.ts +0 -446
- package/scripts/classify-edge-cases.ts +0 -275
- package/scripts/classify-operations-tools.sh +0 -96
- package/scripts/cleanup-mcp-servers.js +0 -115
- package/scripts/diagnose-mcp.js +0 -299
- package/scripts/generate-mcp-config.js +0 -45
- package/scripts/mcp-server-manager.sh +0 -320
- package/scripts/postinstall.js +0 -75
- package/scripts/reset-mcp-servers.js +0 -266
- package/scripts/safe-mcp-cleanup.js +0 -151
- package/scripts/setup-mcp.js +0 -106
- package/scripts/start-mcp-proper.js +0 -76
- package/scripts/start-snowcode.sh +0 -123
- package/scripts/start-sysprops-mcp.js +0 -43
- package/scripts/sync-snow-code-version.js +0 -74
- package/scripts/test-auth-flow.js +0 -172
- package/scripts/test-auth-location-fix.js +0 -84
- package/scripts/test-mcp-manual.js +0 -140
- package/scripts/test-todowrite-timeout.js +0 -108
- package/scripts/update-dependencies.js +0 -90
- package/scripts/update-mcp-config.js +0 -96
- package/scripts/update-snow-code.js +0 -146
- package/scripts/verify-snowcode-fork.sh +0 -141
- package/templates/snow-code-package.json +0 -3
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Second Pass: Classify Edge Case Tools
|
|
5
|
-
*
|
|
6
|
-
* Manually classify the 120 tools that couldn't be auto-classified
|
|
7
|
-
* based on logical categories and functionality.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import * as fs from 'fs';
|
|
11
|
-
import * as path from 'path';
|
|
12
|
-
|
|
13
|
-
const TOOLS_BASE_DIR = path.join(__dirname, '../src/mcp/servicenow-mcp-unified/tools');
|
|
14
|
-
const DRY_RUN = process.argv.includes('--dry-run');
|
|
15
|
-
|
|
16
|
-
// Manual classification of edge cases
|
|
17
|
-
const EDGE_CASE_CLASSIFICATIONS: Record<string, { permission: 'read' | 'write'; reason: string }> = {
|
|
18
|
-
// Utility functions - READ (pure functions, no ServiceNow modifications)
|
|
19
|
-
'snow_timestamp': { permission: 'read', reason: 'Utility function - generates timestamp locally' },
|
|
20
|
-
'snow_sleep': { permission: 'read', reason: 'Utility function - delays execution but no data modification' },
|
|
21
|
-
'snow_sanitize_input': { permission: 'read', reason: 'Utility function - sanitizes data locally' },
|
|
22
|
-
'snow_random_string': { permission: 'read', reason: 'Utility function - generates random string locally' },
|
|
23
|
-
'snow_merge_objects': { permission: 'read', reason: 'Utility function - merges objects locally' },
|
|
24
|
-
'snow_generate_guid': { permission: 'read', reason: 'Utility function - generates GUID locally' },
|
|
25
|
-
'snow_format_date': { permission: 'read', reason: 'Utility function - formats date locally' },
|
|
26
|
-
'snow_encode_query': { permission: 'read', reason: 'Utility function - encodes query string locally' },
|
|
27
|
-
'snow_decode_query': { permission: 'read', reason: 'Utility function - decodes query string locally' },
|
|
28
|
-
'snow_parse_json': { permission: 'read', reason: 'Utility function - parses JSON locally' },
|
|
29
|
-
'snow_parse_xml': { permission: 'read', reason: 'Utility function - parses XML locally' },
|
|
30
|
-
'snow_hash_string': { permission: 'read', reason: 'Utility function - hashes string locally' },
|
|
31
|
-
'snow_base64_encode': { permission: 'read', reason: 'Utility function - encodes base64 locally' },
|
|
32
|
-
'snow_base64_decode': { permission: 'read', reason: 'Utility function - decodes base64 locally' },
|
|
33
|
-
|
|
34
|
-
// Validation/Testing/Preview - READ (only validate, don't modify)
|
|
35
|
-
'snow_widget_test': { permission: 'read', reason: 'Testing function - validates widget without modifying' },
|
|
36
|
-
'snow_preview_widget': { permission: 'read', reason: 'Preview function - renders widget without saving' },
|
|
37
|
-
'snow_debug_widget_fetch': { permission: 'read', reason: 'Debug function - fetches widget data for debugging' },
|
|
38
|
-
|
|
39
|
-
// Discovery/Inspection - READ
|
|
40
|
-
'snow_uib_discover': { permission: 'read', reason: 'Discovery function - reads UI Builder configuration' },
|
|
41
|
-
|
|
42
|
-
// Security Assessment/Scanning - READ (analyze but don't modify)
|
|
43
|
-
'snow_vulnerability_risk_assessment': { permission: 'read', reason: 'Assessment function - analyzes vulnerabilities without modifying' },
|
|
44
|
-
'snow_security_risk_assessment': { permission: 'read', reason: 'Assessment function - analyzes security risks without modifying' },
|
|
45
|
-
'snow_security_dashboard': { permission: 'read', reason: 'Dashboard function - displays security metrics without modifying' },
|
|
46
|
-
'snow_scan_vulnerabilities': { permission: 'read', reason: 'Scan function - scans for vulnerabilities without modifying' },
|
|
47
|
-
'snow_run_compliance_scan': { permission: 'read', reason: 'Scan function - scans compliance without modifying' },
|
|
48
|
-
|
|
49
|
-
// Data transformation - READ (transforms data in-memory, doesn't modify ServiceNow)
|
|
50
|
-
'snow_transform_data': { permission: 'read', reason: 'Transformation function - transforms data locally without ServiceNow modification' },
|
|
51
|
-
|
|
52
|
-
// Virtual Agent - WRITE (sends messages, modifies state)
|
|
53
|
-
'snow_train_va_nlu': { permission: 'write', reason: 'Training function - modifies NLU model in ServiceNow' },
|
|
54
|
-
'snow_send_va_message': { permission: 'write', reason: 'Message function - sends messages and modifies conversation state' },
|
|
55
|
-
'snow_handoff_to_agent': { permission: 'write', reason: 'Handoff function - modifies conversation assignment' },
|
|
56
|
-
|
|
57
|
-
// Update Sets - WRITE (modifies update set state)
|
|
58
|
-
'snow_ensure_active_update_set': { permission: 'write', reason: 'Update set function - creates or switches active update set' },
|
|
59
|
-
|
|
60
|
-
// Property Management - WRITE (bulk operations modify properties)
|
|
61
|
-
'snow_property_io': { permission: 'write', reason: 'Property I/O - imports properties which modifies ServiceNow' },
|
|
62
|
-
'snow_property_bulk': { permission: 'write', reason: 'Bulk operation - modifies multiple properties' },
|
|
63
|
-
|
|
64
|
-
// Security Actions - WRITE (modify permissions, automate responses)
|
|
65
|
-
'snow_escalate_permissions': { permission: 'write', reason: 'Permission escalation - modifies user permissions' },
|
|
66
|
-
'snow_automate_threat_response': { permission: 'write', reason: 'Automation - executes automated threat response actions' },
|
|
67
|
-
|
|
68
|
-
// Reporting/KPI - WRITE (defines/creates KPIs)
|
|
69
|
-
'snow_define_kpi': { permission: 'write', reason: 'Definition function - creates KPI definition in ServiceNow' },
|
|
70
|
-
|
|
71
|
-
// Predictive Intelligence - WRITE (trains models)
|
|
72
|
-
'snow_train_pi_solution': { permission: 'write', reason: 'Training function - trains predictive intelligence model' },
|
|
73
|
-
|
|
74
|
-
// Plugins - WRITE (custom plugins likely modify state)
|
|
75
|
-
'snow_custom_plugin': { permission: 'write', reason: 'Plugin function - executes custom plugin which can modify data' },
|
|
76
|
-
|
|
77
|
-
// Record management with actions - WRITE
|
|
78
|
-
'snow_record_manage': { permission: 'write', reason: 'Management function - creates/updates/deletes records based on action' },
|
|
79
|
-
'snow_catalog_item_manager': { permission: 'write', reason: 'Management function - manages catalog items' },
|
|
80
|
-
'snow_property_manager': { permission: 'write', reason: 'Management function - manages properties' },
|
|
81
|
-
|
|
82
|
-
// Operations that can be both read and write - classify as WRITE (most restrictive)
|
|
83
|
-
'snow_assign_task': { permission: 'write', reason: 'Assignment function - modifies task assignment' },
|
|
84
|
-
'snow_auto_resolve_incident': { permission: 'write', reason: 'Resolution function - closes incidents automatically' },
|
|
85
|
-
'snow_manage_group_membership': { permission: 'write', reason: 'Management function - modifies group memberships' },
|
|
86
|
-
'snow_cleanup_test_artifacts': { permission: 'write', reason: 'Cleanup function - deletes test artifacts' },
|
|
87
|
-
|
|
88
|
-
// Workflow/Process - WRITE
|
|
89
|
-
'snow_execute_workflow': { permission: 'write', reason: 'Execution function - triggers workflow execution' },
|
|
90
|
-
|
|
91
|
-
// CI/Asset operations - WRITE
|
|
92
|
-
'snow_reconcile_ci': { permission: 'write', reason: 'Reconciliation function - updates CI records' },
|
|
93
|
-
'snow_track_asset_lifecycle': { permission: 'write', reason: 'Tracking function - updates asset lifecycle state' },
|
|
94
|
-
'snow_optimize_licenses': { permission: 'write', reason: 'Optimization function - modifies license allocations' },
|
|
95
|
-
'snow_asset_discovery': { permission: 'write', reason: 'Discovery function - creates/updates asset records' },
|
|
96
|
-
|
|
97
|
-
// Advanced analysis with ML predictions - READ (predictions don't modify source data)
|
|
98
|
-
'snow_ml_predict': { permission: 'read', reason: 'Prediction function - generates predictions without modifying data' },
|
|
99
|
-
'snow_ai_classify': { permission: 'read', reason: 'Classification function - classifies data without modifying' },
|
|
100
|
-
'snow_anomaly_detection': { permission: 'read', reason: 'Detection function - detects anomalies without modifying' },
|
|
101
|
-
'snow_duplicate_detection': { permission: 'read', reason: 'Detection function - finds duplicates without modifying' },
|
|
102
|
-
'snow_fuzzy_search': { permission: 'read', reason: 'Search function - performs fuzzy search without modifying' },
|
|
103
|
-
'snow_autocomplete': { permission: 'read', reason: 'Autocomplete function - suggests completions without modifying' },
|
|
104
|
-
'snow_recommendation_engine': { permission: 'read', reason: 'Recommendation function - generates recommendations without modifying' },
|
|
105
|
-
'snow_sentiment_analysis': { permission: 'read', reason: 'Analysis function - analyzes sentiment without modifying' },
|
|
106
|
-
|
|
107
|
-
// Aggregation/Metrics - READ
|
|
108
|
-
'snow_aggregate_metrics': { permission: 'read', reason: 'Aggregation function - aggregates metrics without modifying' },
|
|
109
|
-
|
|
110
|
-
// Pattern/Predictive analysis - READ
|
|
111
|
-
'snow_pattern_analysis': { permission: 'read', reason: 'Analysis function - analyzes patterns without modifying' },
|
|
112
|
-
'snow_predictive_analysis': { permission: 'read', reason: 'Analysis function - performs predictive analysis without modifying' },
|
|
113
|
-
|
|
114
|
-
// Data quality/optimization analysis - READ
|
|
115
|
-
'snow_analyze_data_quality': { permission: 'read', reason: 'Analysis function - analyzes data quality without modifying' },
|
|
116
|
-
'snow_optimize_queries': { permission: 'read', reason: 'Analysis function - suggests query optimizations without modifying' },
|
|
117
|
-
|
|
118
|
-
// CI operations that are primarily read
|
|
119
|
-
'snow_ci_health_check': { permission: 'read', reason: 'Health check - validates CI health without modifying' },
|
|
120
|
-
'snow_get_ci_details': { permission: 'read', reason: 'Get function - retrieves CI details' },
|
|
121
|
-
'snow_get_ci_history': { permission: 'read', reason: 'Get function - retrieves CI history' },
|
|
122
|
-
'snow_get_ci_impact': { permission: 'read', reason: 'Get function - analyzes CI impact' },
|
|
123
|
-
'snow_get_ci_relationships': { permission: 'read', reason: 'Get function - retrieves CI relationships' },
|
|
124
|
-
'snow_get_event_correlation': { permission: 'read', reason: 'Get function - retrieves event correlations' },
|
|
125
|
-
'snow_impact_analysis': { permission: 'read', reason: 'Analysis function - analyzes impact without modifying' },
|
|
126
|
-
|
|
127
|
-
// Change operations - READ for query, WRITE for manage
|
|
128
|
-
'snow_change_query': { permission: 'read', reason: 'Query function - retrieves change records' },
|
|
129
|
-
|
|
130
|
-
// Calendar/Schedule - READ (gets calendar info)
|
|
131
|
-
'snow_calendar': { permission: 'read', reason: 'Calendar function - retrieves calendar information' },
|
|
132
|
-
|
|
133
|
-
// SLA calculations - READ
|
|
134
|
-
'snow_calculate_sla_duration': { permission: 'read', reason: 'Calculation function - calculates SLA duration locally' },
|
|
135
|
-
|
|
136
|
-
// Connectors/Batch - depends on action, classify as WRITE (can modify)
|
|
137
|
-
'snow_batch_request': { permission: 'write', reason: 'Batch function - can execute multiple operations including writes' },
|
|
138
|
-
|
|
139
|
-
// Operations analysis - READ
|
|
140
|
-
'snow_analyze_incident': { permission: 'read', reason: 'Analysis function - analyzes incident without modifying' },
|
|
141
|
-
'snow_operational_metrics': { permission: 'read', reason: 'Metrics function - retrieves operational metrics' },
|
|
142
|
-
|
|
143
|
-
// User operations - depends, but lookup is READ
|
|
144
|
-
'snow_user_lookup': { permission: 'read', reason: 'Lookup function - retrieves user information' },
|
|
145
|
-
|
|
146
|
-
// Catalog search - READ
|
|
147
|
-
'snow_catalog_item_search': { permission: 'read', reason: 'Search function - searches catalog items' },
|
|
148
|
-
'snow_comprehensive_search': { permission: 'read', reason: 'Search function - performs comprehensive search' },
|
|
149
|
-
|
|
150
|
-
// Incident operations
|
|
151
|
-
'snow_update_incident': { permission: 'write', reason: 'Update function - modifies incident records' },
|
|
152
|
-
|
|
153
|
-
// Asset reports/compliance - READ
|
|
154
|
-
'snow_asset_compliance_report': { permission: 'read', reason: 'Report function - generates compliance report' },
|
|
155
|
-
|
|
156
|
-
// Test/ATF operations - discovery is READ, execution is WRITE
|
|
157
|
-
'snow_discover_atf_tests': { permission: 'read', reason: 'Discovery function - lists ATF tests' },
|
|
158
|
-
'snow_get_atf_results': { permission: 'read', reason: 'Get function - retrieves test results' },
|
|
159
|
-
|
|
160
|
-
// Attachments operations
|
|
161
|
-
'snow_get_attachments': { permission: 'read', reason: 'Get function - retrieves attachments' },
|
|
162
|
-
|
|
163
|
-
// Automation operations - discovery is READ, execution is WRITE
|
|
164
|
-
'snow_discover_automation_jobs': { permission: 'read', reason: 'Discovery function - lists automation jobs' },
|
|
165
|
-
'snow_discover_events': { permission: 'read', reason: 'Discovery function - lists events' },
|
|
166
|
-
'snow_discover_schedules': { permission: 'read', reason: 'Discovery function - lists schedules' },
|
|
167
|
-
'snow_get_logs': { permission: 'read', reason: 'Get function - retrieves system logs' },
|
|
168
|
-
'snow_get_script_output': { permission: 'read', reason: 'Get function - retrieves script execution output' },
|
|
169
|
-
|
|
170
|
-
// Catalog operations
|
|
171
|
-
'snow_discover_catalogs': { permission: 'read', reason: 'Discovery function - lists catalogs' },
|
|
172
|
-
'snow_get_catalog_item_details': { permission: 'read', reason: 'Get function - retrieves catalog item details' },
|
|
173
|
-
|
|
174
|
-
// Approvals - get pending is READ
|
|
175
|
-
'snow_get_pending_approvals': { permission: 'read', reason: 'Get function - retrieves pending approvals' },
|
|
176
|
-
};
|
|
177
|
-
|
|
178
|
-
function addPermissionFields(filePath: string, permission: 'read' | 'write', reason: string): boolean {
|
|
179
|
-
try {
|
|
180
|
-
let content = fs.readFileSync(filePath, 'utf-8');
|
|
181
|
-
|
|
182
|
-
// Check if already classified
|
|
183
|
-
if (content.includes('permission:') && content.includes('allowedRoles:')) {
|
|
184
|
-
return false;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
// Find insertion point
|
|
188
|
-
const frequencyMatch = content.match(/frequency:\s*['"][\w-]+['"],?/);
|
|
189
|
-
if (!frequencyMatch) {
|
|
190
|
-
console.error(` โ ๏ธ Could not find frequency field in ${path.basename(filePath)}`);
|
|
191
|
-
return false;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
const roles = permission === 'read'
|
|
195
|
-
? "['developer', 'stakeholder', 'admin']"
|
|
196
|
-
: "['developer', 'admin']";
|
|
197
|
-
|
|
198
|
-
const permissionBlock = `\n\n // ๐ Permission enforcement (Q1 2025)\n` +
|
|
199
|
-
` // Classification: ${permission.toUpperCase()} - ${reason}\n` +
|
|
200
|
-
` permission: '${permission}',\n` +
|
|
201
|
-
` allowedRoles: ${roles},`;
|
|
202
|
-
|
|
203
|
-
const insertIndex = frequencyMatch.index! + frequencyMatch[0].length;
|
|
204
|
-
content = content.slice(0, insertIndex) + permissionBlock + content.slice(insertIndex);
|
|
205
|
-
|
|
206
|
-
if (!DRY_RUN) {
|
|
207
|
-
fs.writeFileSync(filePath, content, 'utf-8');
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
return true;
|
|
211
|
-
} catch (error) {
|
|
212
|
-
console.error(` โ Error updating ${path.basename(filePath)}:`, error);
|
|
213
|
-
return false;
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
async function classifyEdgeCases(): Promise<void> {
|
|
218
|
-
console.log('๐ง Classifying Edge Case Tools (Second Pass)...\n');
|
|
219
|
-
|
|
220
|
-
let updated = 0;
|
|
221
|
-
let alreadyClassified = 0;
|
|
222
|
-
let notFound = 0;
|
|
223
|
-
|
|
224
|
-
for (const [toolName, classification] of Object.entries(EDGE_CASE_CLASSIFICATIONS)) {
|
|
225
|
-
// Find the tool file
|
|
226
|
-
const possiblePath = path.join(TOOLS_BASE_DIR, `**/${toolName}.ts`);
|
|
227
|
-
|
|
228
|
-
// Simple glob implementation - search in all subdirectories
|
|
229
|
-
let filePath: string | null = null;
|
|
230
|
-
const searchDir = (dir: string) => {
|
|
231
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
232
|
-
for (const entry of entries) {
|
|
233
|
-
const fullPath = path.join(dir, entry.name);
|
|
234
|
-
if (entry.isDirectory()) {
|
|
235
|
-
searchDir(fullPath);
|
|
236
|
-
} else if (entry.isFile() && entry.name === `${toolName}.ts`) {
|
|
237
|
-
filePath = fullPath;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
searchDir(TOOLS_BASE_DIR);
|
|
243
|
-
|
|
244
|
-
if (!filePath) {
|
|
245
|
-
console.log(` โ ๏ธ ${toolName} - File not found`);
|
|
246
|
-
notFound++;
|
|
247
|
-
continue;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
const success = addPermissionFields(filePath, classification.permission, classification.reason);
|
|
251
|
-
|
|
252
|
-
if (success) {
|
|
253
|
-
updated++;
|
|
254
|
-
console.log(` โ
${toolName} โ ${classification.permission.toUpperCase()}`);
|
|
255
|
-
} else {
|
|
256
|
-
alreadyClassified++;
|
|
257
|
-
console.log(` โน๏ธ ${toolName} - Already classified`);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
console.log(`\nโ
Second pass complete!\n`);
|
|
262
|
-
console.log(` โ
Classified: ${updated}`);
|
|
263
|
-
console.log(` โน๏ธ Already done: ${alreadyClassified}`);
|
|
264
|
-
console.log(` โ ๏ธ Not found: ${notFound}`);
|
|
265
|
-
console.log(`\n๐ Total edge cases in dictionary: ${Object.keys(EDGE_CASE_CLASSIFICATIONS).length}\n`);
|
|
266
|
-
|
|
267
|
-
if (DRY_RUN) {
|
|
268
|
-
console.log('๐ DRY RUN MODE - No files were modified\n');
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
classifyEdgeCases().catch(error => {
|
|
273
|
-
console.error('โ Fatal error:', error);
|
|
274
|
-
process.exit(1);
|
|
275
|
-
});
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# Script to add permission fields to operations tools
|
|
4
|
-
# Phase 1.2: Classify Core Operations tools
|
|
5
|
-
|
|
6
|
-
set -e
|
|
7
|
-
|
|
8
|
-
TOOLS_DIR="/Users/nielsvanderwerf/snow-flow/src/mcp/servicenow-mcp-unified/tools/operations"
|
|
9
|
-
|
|
10
|
-
echo "๐ง Classifying Core Operations tools..."
|
|
11
|
-
echo ""
|
|
12
|
-
|
|
13
|
-
# READ tools (query, get, discover, search, analyze, lookup, metrics)
|
|
14
|
-
READ_TOOLS=(
|
|
15
|
-
"snow_query_incidents"
|
|
16
|
-
"snow_query_problems"
|
|
17
|
-
"snow_query_requests"
|
|
18
|
-
"snow_get_by_sysid"
|
|
19
|
-
"snow_discover_table_fields"
|
|
20
|
-
"snow_cmdb_search"
|
|
21
|
-
"snow_comprehensive_search"
|
|
22
|
-
"snow_catalog_item_search"
|
|
23
|
-
"snow_user_lookup"
|
|
24
|
-
"snow_operational_metrics"
|
|
25
|
-
"snow_pattern_analysis"
|
|
26
|
-
"snow_predictive_analysis"
|
|
27
|
-
"snow_analyze_incident"
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
# WRITE tools (create, update, assign, attach, manage, cleanup, resolve)
|
|
31
|
-
WRITE_TOOLS=(
|
|
32
|
-
"snow_create_incident"
|
|
33
|
-
"snow_create_user_group"
|
|
34
|
-
"snow_update_incident"
|
|
35
|
-
"snow_assign_task"
|
|
36
|
-
"snow_attach_file"
|
|
37
|
-
"snow_auto_resolve_incident"
|
|
38
|
-
"snow_catalog_item_manager"
|
|
39
|
-
"snow_manage_group_membership"
|
|
40
|
-
"snow_record_manage"
|
|
41
|
-
"snow_cleanup_test_artifacts"
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
echo "โ
READ tools: ${#READ_TOOLS[@]}"
|
|
45
|
-
echo "โ WRITE tools: ${#WRITE_TOOLS[@]}"
|
|
46
|
-
echo ""
|
|
47
|
-
|
|
48
|
-
# Function to add permission fields to tool file
|
|
49
|
-
add_permissions() {
|
|
50
|
-
local file="$1"
|
|
51
|
-
local permission="$2"
|
|
52
|
-
local roles="$3"
|
|
53
|
-
|
|
54
|
-
if [ ! -f "$file" ]; then
|
|
55
|
-
echo "โ ๏ธ File not found: $file"
|
|
56
|
-
return
|
|
57
|
-
fi
|
|
58
|
-
|
|
59
|
-
# Check if already has permission field
|
|
60
|
-
if grep -q "permission:" "$file"; then
|
|
61
|
-
echo " โน๏ธ Already classified: $(basename $file)"
|
|
62
|
-
return
|
|
63
|
-
fi
|
|
64
|
-
|
|
65
|
-
# Find the line with "frequency:" and add permission fields after it
|
|
66
|
-
# Using perl for in-place editing with backup
|
|
67
|
-
perl -i.bak -pe '
|
|
68
|
-
if (/frequency:.*,?$/) {
|
|
69
|
-
$_ .= "\n\n // ๐ Permission enforcement (Q1 2025)\n";
|
|
70
|
-
$_ .= " // Classification: '"$permission"'\n";
|
|
71
|
-
$_ .= " permission: '"$permission"',\n";
|
|
72
|
-
$_ .= " allowedRoles: '"$roles"',\n";
|
|
73
|
-
}
|
|
74
|
-
' "$file"
|
|
75
|
-
|
|
76
|
-
echo " โ
Classified: $(basename $file) โ $permission"
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
echo "๐ Processing READ tools..."
|
|
80
|
-
for tool in "${READ_TOOLS[@]}"; do
|
|
81
|
-
file="$TOOLS_DIR/${tool}.ts"
|
|
82
|
-
add_permissions "$file" "read" "['developer', 'stakeholder', 'admin']"
|
|
83
|
-
done
|
|
84
|
-
|
|
85
|
-
echo ""
|
|
86
|
-
echo "๐ Processing WRITE tools..."
|
|
87
|
-
for tool in "${WRITE_TOOLS[@]}"; do
|
|
88
|
-
file="$TOOLS_DIR/${tool}.ts"
|
|
89
|
-
add_permissions "$file" "write" "['developer', 'admin']"
|
|
90
|
-
done
|
|
91
|
-
|
|
92
|
-
echo ""
|
|
93
|
-
echo "โ
Done! Classified $(( ${#READ_TOOLS[@]} + ${#WRITE_TOOLS[@]} )) operations tools"
|
|
94
|
-
echo ""
|
|
95
|
-
echo "๐ To verify changes:"
|
|
96
|
-
echo " git diff $TOOLS_DIR"
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* MCP Server Cleanup Script
|
|
5
|
-
* Prevents duplicate MCP servers and memory exhaustion
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const { exec } = require('child_process');
|
|
9
|
-
const { promisify } = require('util');
|
|
10
|
-
const execAsync = promisify(exec);
|
|
11
|
-
|
|
12
|
-
async function cleanupMCPServers() {
|
|
13
|
-
console.log('๐งน Cleaning up MCP servers...\n');
|
|
14
|
-
|
|
15
|
-
try {
|
|
16
|
-
// 1. Check for running MCP processes
|
|
17
|
-
const { stdout: psOutput } = await execAsync('ps aux | grep -E "node.*mcp" | grep -v grep | wc -l');
|
|
18
|
-
const processCount = parseInt(psOutput.trim());
|
|
19
|
-
|
|
20
|
-
if (processCount > 0) {
|
|
21
|
-
console.log(`โ ๏ธ Found ${processCount} running MCP processes`);
|
|
22
|
-
console.log('๐ช Killing all MCP processes...');
|
|
23
|
-
|
|
24
|
-
// Kill all MCP processes
|
|
25
|
-
await execAsync('pkill -f "node.*mcp"').catch(() => {
|
|
26
|
-
// Ignore errors if no processes found
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
// Wait for processes to terminate
|
|
30
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
31
|
-
|
|
32
|
-
console.log('โ
All MCP processes terminated\n');
|
|
33
|
-
} else {
|
|
34
|
-
console.log('โ
No MCP processes running\n');
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// 2. Clean up any stale lock files
|
|
38
|
-
console.log('๐ Cleaning up lock files...');
|
|
39
|
-
await execAsync('rm -f /tmp/mcp-*.lock').catch(() => {});
|
|
40
|
-
await execAsync('rm -f ~/.claude/mcp-*.lock').catch(() => {});
|
|
41
|
-
await execAsync('rm -f ~/.claude/mcp-servers.lock').catch(() => {});
|
|
42
|
-
|
|
43
|
-
// 3. Check memory usage
|
|
44
|
-
const { stdout: memOutput } = await execAsync('ps aux | grep node | awk \'{sum+=$6} END {print sum/1024}\'');
|
|
45
|
-
const nodeMemoryMB = parseFloat(memOutput.trim());
|
|
46
|
-
|
|
47
|
-
console.log(`๐ Node.js memory usage: ${nodeMemoryMB.toFixed(2)} MB\n`);
|
|
48
|
-
|
|
49
|
-
if (nodeMemoryMB > 1000) {
|
|
50
|
-
console.log('โ ๏ธ High memory usage detected!');
|
|
51
|
-
console.log('๐ก Recommendation: Restart your terminal or run "killall node"\n');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// 4. Create singleton lock mechanism
|
|
55
|
-
console.log('๐ Setting up singleton lock mechanism...');
|
|
56
|
-
const lockScript = `
|
|
57
|
-
const fs = require('fs');
|
|
58
|
-
const path = require('path');
|
|
59
|
-
|
|
60
|
-
const lockFile = path.join(process.env.HOME, '.claude', 'mcp-singleton.lock');
|
|
61
|
-
const pid = process.pid;
|
|
62
|
-
|
|
63
|
-
// Check if lock exists
|
|
64
|
-
if (fs.existsSync(lockFile)) {
|
|
65
|
-
const existingPid = fs.readFileSync(lockFile, 'utf8');
|
|
66
|
-
try {
|
|
67
|
-
// Check if process is still running
|
|
68
|
-
process.kill(existingPid, 0);
|
|
69
|
-
console.error('MCP servers already running with PID:', existingPid);
|
|
70
|
-
process.exit(1);
|
|
71
|
-
} catch (e) {
|
|
72
|
-
// Process not running, remove stale lock
|
|
73
|
-
fs.unlinkSync(lockFile);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Create lock
|
|
78
|
-
fs.mkdirSync(path.dirname(lockFile), { recursive: true });
|
|
79
|
-
fs.writeFileSync(lockFile, pid.toString());
|
|
80
|
-
|
|
81
|
-
// Clean up on exit
|
|
82
|
-
process.on('exit', () => {
|
|
83
|
-
try {
|
|
84
|
-
fs.unlinkSync(lockFile);
|
|
85
|
-
} catch (e) {}
|
|
86
|
-
});
|
|
87
|
-
`;
|
|
88
|
-
|
|
89
|
-
// Save singleton script
|
|
90
|
-
const fs = require('fs');
|
|
91
|
-
const path = require('path');
|
|
92
|
-
const singletonPath = path.join(__dirname, '..', 'dist', 'mcp', 'singleton-check.js');
|
|
93
|
-
fs.writeFileSync(singletonPath, lockScript);
|
|
94
|
-
console.log('โ
Singleton mechanism created\n');
|
|
95
|
-
|
|
96
|
-
// 5. Report status
|
|
97
|
-
console.log('๐ Cleanup Summary:');
|
|
98
|
-
console.log('โ'.repeat(40));
|
|
99
|
-
console.log('โ
All MCP processes terminated');
|
|
100
|
-
console.log('โ
Lock files cleaned');
|
|
101
|
-
console.log('โ
Singleton mechanism installed');
|
|
102
|
-
console.log(`โ
Memory usage: ${nodeMemoryMB.toFixed(2)} MB`);
|
|
103
|
-
console.log('\n๐ฏ Next Steps:');
|
|
104
|
-
console.log('1. Run "npm run build" to rebuild');
|
|
105
|
-
console.log('2. Use "snow-flow mcp start" to start servers properly');
|
|
106
|
-
console.log('3. Monitor with "snow-flow mcp status"');
|
|
107
|
-
|
|
108
|
-
} catch (error) {
|
|
109
|
-
console.error('โ Cleanup failed:', error.message);
|
|
110
|
-
process.exit(1);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Run cleanup
|
|
115
|
-
cleanupMCPServers().catch(console.error);
|