mcp-nervous-system 1.9.4 → 1.10.0
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/index.js +409 -5
- package/package.json +1 -1
- package/package.json.bak.1772792496 +0 -42
- package/package.json.bak.1772792812 +0 -42
- package/package.json.bak.1772809772 +0 -42
- package/package.json.bak.1772814645 +0 -42
- package/package.json.bak.1772814975 +0 -42
package/index.js
CHANGED
|
@@ -192,7 +192,7 @@ const MCP_VERSION = '2024-11-05';
|
|
|
192
192
|
// Server info
|
|
193
193
|
const SERVER_INFO = {
|
|
194
194
|
name: 'nervous-system',
|
|
195
|
-
version: '1.
|
|
195
|
+
version: '1.10.0'
|
|
196
196
|
};
|
|
197
197
|
|
|
198
198
|
// ============================================================
|
|
@@ -201,7 +201,7 @@ const SERVER_INFO = {
|
|
|
201
201
|
|
|
202
202
|
const FRAMEWORK = {
|
|
203
203
|
name: 'The Nervous System',
|
|
204
|
-
version: '1.
|
|
204
|
+
version: '1.10.0',
|
|
205
205
|
author: 'Arthur Palyan',
|
|
206
206
|
tagline: 'Anthropic built the brain. Arthur built the nervous system that keeps it from hurting itself.',
|
|
207
207
|
problem: 'LLMs lose context between sessions, loop on problems instead of dispatching, silently fail without progress notes, edit protected files, drift from the real problem, and solve instead of asking.',
|
|
@@ -775,6 +775,115 @@ const TOOLS = [
|
|
|
775
775
|
bot: { type: 'string', description: 'Check a specific bot file path, or omit to check all 10 public bots' }
|
|
776
776
|
}
|
|
777
777
|
}
|
|
778
|
+
},
|
|
779
|
+
{
|
|
780
|
+
name: 'usage_report',
|
|
781
|
+
annotations: { title: 'Usage Report', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
782
|
+
description: 'Check API token usage per bot per day. Shows which bots are consuming the most tokens and flags anomalies. Use this to monitor costs and catch runaway knowledge files.',
|
|
783
|
+
inputSchema: {
|
|
784
|
+
type: 'object',
|
|
785
|
+
properties: {
|
|
786
|
+
days: { type: 'number', description: 'Number of days to show (default: 3)' }
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
},
|
|
790
|
+
// v1.10.0 Infrastructure Tools
|
|
791
|
+
{
|
|
792
|
+
name: 'check_dependencies',
|
|
793
|
+
annotations: { title: 'Dependency Mapper', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
794
|
+
description: 'Generate dependency map showing which files each PM2 process requires. Returns dependency-map.json content.',
|
|
795
|
+
inputSchema: { type: 'object', properties: {} }
|
|
796
|
+
},
|
|
797
|
+
{
|
|
798
|
+
name: 'create_snapshot',
|
|
799
|
+
annotations: { title: 'System Snapshot', readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
800
|
+
description: 'Create full system snapshot with one-command rollback script. Returns snapshot location, file count, and RESTORE.sh path.',
|
|
801
|
+
inputSchema: { type: 'object', properties: {} }
|
|
802
|
+
},
|
|
803
|
+
{
|
|
804
|
+
name: 'check_session_diff',
|
|
805
|
+
annotations: { title: 'Session Diff', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
806
|
+
description: 'Show what changed since last session - files modified, processes changed, alerts triggered. Returns SESSION_DIFF.md content.',
|
|
807
|
+
inputSchema: { type: 'object', properties: {} }
|
|
808
|
+
},
|
|
809
|
+
{
|
|
810
|
+
name: 'fix_doc_drift',
|
|
811
|
+
annotations: { title: 'Doc Drift Fixer', readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
812
|
+
description: 'Auto-fix drift between docs and reality (process counts, versions, port numbers). Use dry_run=true to preview changes.',
|
|
813
|
+
inputSchema: {
|
|
814
|
+
type: 'object',
|
|
815
|
+
properties: {
|
|
816
|
+
dry_run: { type: 'boolean', description: 'If true, only report drift without fixing. Default: true' }
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
},
|
|
820
|
+
{
|
|
821
|
+
name: 'get_health_status',
|
|
822
|
+
annotations: { title: 'Health Dashboard', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
823
|
+
description: 'Generate current system health snapshot - RAM, disk, CPU, process states, crash loops, and alerts.',
|
|
824
|
+
inputSchema: { type: 'object', properties: {} }
|
|
825
|
+
},
|
|
826
|
+
{
|
|
827
|
+
name: 'test_deployment',
|
|
828
|
+
annotations: { title: 'Deployment Tester', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
829
|
+
description: 'Run 5-step test pipeline on a file before deployment: preflight, syntax, dependencies, ports, memory.',
|
|
830
|
+
inputSchema: {
|
|
831
|
+
type: 'object',
|
|
832
|
+
properties: {
|
|
833
|
+
filepath: { type: 'string', description: 'Path to file to test before deployment' }
|
|
834
|
+
},
|
|
835
|
+
required: ['filepath']
|
|
836
|
+
}
|
|
837
|
+
},
|
|
838
|
+
{
|
|
839
|
+
name: 'check_page_changes',
|
|
840
|
+
annotations: { title: 'Page Changelog', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
841
|
+
description: 'Detect changes to public pages since last check. Returns list of changed pages with diffs.',
|
|
842
|
+
inputSchema: {
|
|
843
|
+
type: 'object',
|
|
844
|
+
properties: {
|
|
845
|
+
page: { type: 'string', description: 'Specific page to check (family, gateway, health), or omit for all' },
|
|
846
|
+
since: { type: 'string', description: 'ISO date to check changes since (e.g. 2026-03-01)' }
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
},
|
|
850
|
+
{
|
|
851
|
+
name: 'check_archive_safety',
|
|
852
|
+
annotations: { title: 'Archive Safety Check', readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
853
|
+
description: 'Check if a file is safe to archive - verifies it is not in use by active PM2 processes, not required by other files, and not in the untouchable list.',
|
|
854
|
+
inputSchema: {
|
|
855
|
+
type: 'object',
|
|
856
|
+
properties: {
|
|
857
|
+
filepath: { type: 'string', description: 'Path to file to check for archive safety' }
|
|
858
|
+
},
|
|
859
|
+
required: ['filepath']
|
|
860
|
+
}
|
|
861
|
+
},
|
|
862
|
+
// NEW: Accountability Check
|
|
863
|
+
{
|
|
864
|
+
name: 'accountability_check',
|
|
865
|
+
annotations: {
|
|
866
|
+
title: 'Accountability Check',
|
|
867
|
+
readOnlyHint: true,
|
|
868
|
+
destructiveHint: false,
|
|
869
|
+
idempotentHint: true,
|
|
870
|
+
openWorldHint: false
|
|
871
|
+
},
|
|
872
|
+
description: 'Detects when an LLM agent fabricated a solution instead of finding the real one. Scans for: placeholder credentials next to real ones in backups, duplicate files/directories serving the same purpose, config files with defaults when populated versions exist elsewhere, and recently created workarounds for things that already exist. Run this after every session to catch fabrication before it costs time and money.',
|
|
873
|
+
inputSchema: {
|
|
874
|
+
type: 'object',
|
|
875
|
+
properties: {
|
|
876
|
+
scope: {
|
|
877
|
+
type: 'string',
|
|
878
|
+
enum: ['full', 'credentials', 'duplicates', 'workarounds'],
|
|
879
|
+
description: 'What to check. full = all checks. credentials = scan for placeholder keys next to real ones. duplicates = find files/dirs that duplicate existing ones. workarounds = detect recently created alternatives to existing resources.'
|
|
880
|
+
},
|
|
881
|
+
path: {
|
|
882
|
+
type: 'string',
|
|
883
|
+
description: 'Specific path to check (default: project root)'
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
}
|
|
778
887
|
}
|
|
779
888
|
];
|
|
780
889
|
|
|
@@ -2621,6 +2730,70 @@ function runPrePublishAudit(sourceFile) {
|
|
|
2621
2730
|
};
|
|
2622
2731
|
}
|
|
2623
2732
|
|
|
2733
|
+
// ============================================================
|
|
2734
|
+
// Infrastructure Script Runner (v1.10.0)
|
|
2735
|
+
// ============================================================
|
|
2736
|
+
function runInfraScript(scriptPath, args) {
|
|
2737
|
+
var timestamp = new Date().toISOString();
|
|
2738
|
+
try {
|
|
2739
|
+
if (!fs.existsSync(scriptPath)) {
|
|
2740
|
+
return { error: 'Script not found: ' + scriptPath, timestamp: timestamp };
|
|
2741
|
+
}
|
|
2742
|
+
var cmd = 'node ' + JSON.stringify(scriptPath);
|
|
2743
|
+
if (args && args.length > 0) {
|
|
2744
|
+
cmd += ' ' + args.map(function(a) { return JSON.stringify(a); }).join(' ');
|
|
2745
|
+
}
|
|
2746
|
+
var output = execSync(cmd, { timeout: 60000, encoding: 'utf8', maxBuffer: 1024 * 1024 });
|
|
2747
|
+
// Try to parse as JSON, otherwise return raw
|
|
2748
|
+
try {
|
|
2749
|
+
var parsed = JSON.parse(output);
|
|
2750
|
+
parsed._timestamp = timestamp;
|
|
2751
|
+
parsed._script = path.basename(scriptPath);
|
|
2752
|
+
return parsed;
|
|
2753
|
+
} catch (e) {
|
|
2754
|
+
return { output: output.trim(), timestamp: timestamp, script: path.basename(scriptPath) };
|
|
2755
|
+
}
|
|
2756
|
+
} catch (e) {
|
|
2757
|
+
var stderr = e.stderr ? e.stderr.toString().substring(0, 500) : '';
|
|
2758
|
+
var stdout = e.stdout ? e.stdout.toString().substring(0, 2000) : '';
|
|
2759
|
+
// If script produced stdout, treat it as valid output (e.g. BLOCKED results)
|
|
2760
|
+
if (stdout) {
|
|
2761
|
+
try {
|
|
2762
|
+
var parsed = JSON.parse(stdout);
|
|
2763
|
+
parsed._timestamp = timestamp;
|
|
2764
|
+
parsed._script = path.basename(scriptPath);
|
|
2765
|
+
parsed._exitCode = e.status || 1;
|
|
2766
|
+
return parsed;
|
|
2767
|
+
} catch (pe) {
|
|
2768
|
+
return { output: stdout.trim(), exitCode: e.status || 1, timestamp: timestamp, script: path.basename(scriptPath) };
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2771
|
+
return { error: e.message, stderr: stderr, timestamp: timestamp, script: path.basename(scriptPath) };
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
|
|
2775
|
+
function runInfraShell(scriptPath, args) {
|
|
2776
|
+
var timestamp = new Date().toISOString();
|
|
2777
|
+
try {
|
|
2778
|
+
if (!fs.existsSync(scriptPath)) {
|
|
2779
|
+
return { error: 'Script not found: ' + scriptPath, timestamp: timestamp };
|
|
2780
|
+
}
|
|
2781
|
+
var cmd = 'bash ' + JSON.stringify(scriptPath);
|
|
2782
|
+
if (args && args.length > 0) {
|
|
2783
|
+
cmd += ' ' + args.map(function(a) { return JSON.stringify(a); }).join(' ');
|
|
2784
|
+
}
|
|
2785
|
+
var output = execSync(cmd, { timeout: 30000, encoding: 'utf8' });
|
|
2786
|
+
return { output: output.trim(), timestamp: timestamp, script: path.basename(scriptPath) };
|
|
2787
|
+
} catch (e) {
|
|
2788
|
+
var stderr = e.stderr ? e.stderr.toString().substring(0, 500) : '';
|
|
2789
|
+
var stdout = e.stdout ? e.stdout.toString().substring(0, 2000) : '';
|
|
2790
|
+
if (stdout) {
|
|
2791
|
+
return { output: stdout.trim(), exitCode: e.status || 1, timestamp: timestamp, script: path.basename(scriptPath) };
|
|
2792
|
+
}
|
|
2793
|
+
return { error: e.message, stderr: stderr, timestamp: timestamp, script: path.basename(scriptPath) };
|
|
2794
|
+
}
|
|
2795
|
+
}
|
|
2796
|
+
|
|
2624
2797
|
// ============================================================
|
|
2625
2798
|
// Handle tool calls
|
|
2626
2799
|
// ============================================================
|
|
@@ -2844,11 +3017,242 @@ function handleToolCall(name, args) {
|
|
|
2844
3017
|
return runBotComplianceCheck(args.bot);
|
|
2845
3018
|
}
|
|
2846
3019
|
|
|
3020
|
+
case 'usage_report': {
|
|
3021
|
+
return runUsageReport(args.days);
|
|
3022
|
+
}
|
|
3023
|
+
|
|
3024
|
+
// v1.10.0 Infrastructure Tools
|
|
3025
|
+
case 'check_dependencies': {
|
|
3026
|
+
return runInfraScript('/root/family-workers/dependency-mapper.js', []);
|
|
3027
|
+
}
|
|
3028
|
+
|
|
3029
|
+
case 'create_snapshot': {
|
|
3030
|
+
return runInfraScript('/root/family-workers/snapshot-manager.js', []);
|
|
3031
|
+
}
|
|
3032
|
+
|
|
3033
|
+
case 'check_session_diff': {
|
|
3034
|
+
return runInfraScript('/root/family-workers/session-diff.js', []);
|
|
3035
|
+
}
|
|
3036
|
+
|
|
3037
|
+
case 'fix_doc_drift': {
|
|
3038
|
+
var dryRunFlag = (args.dry_run !== false) ? '--dry-run' : '';
|
|
3039
|
+
return runInfraScript('/root/family-workers/doc-drift-fixer.js', dryRunFlag ? [dryRunFlag] : []);
|
|
3040
|
+
}
|
|
3041
|
+
|
|
3042
|
+
case 'get_health_status': {
|
|
3043
|
+
return runInfraScript('/root/family-workers/health-dashboard.js', []);
|
|
3044
|
+
}
|
|
3045
|
+
|
|
3046
|
+
case 'test_deployment': {
|
|
3047
|
+
return runInfraScript('/root/family-workers/staging-deploy.js', [args.filepath]);
|
|
3048
|
+
}
|
|
3049
|
+
|
|
3050
|
+
case 'check_page_changes': {
|
|
3051
|
+
var pageArgs = [];
|
|
3052
|
+
if (args.page) pageArgs.push('--page', args.page);
|
|
3053
|
+
if (args.since) pageArgs.push('--since', args.since);
|
|
3054
|
+
return runInfraScript('/root/family-workers/page-changelog.js', pageArgs);
|
|
3055
|
+
}
|
|
3056
|
+
|
|
3057
|
+
case 'check_archive_safety': {
|
|
3058
|
+
return runInfraShell('/root/preflight-archive.sh', [args.filepath]);
|
|
3059
|
+
}
|
|
3060
|
+
|
|
3061
|
+
case 'accountability_check': {
|
|
3062
|
+
return runAccountabilityCheck(args.scope, args.path);
|
|
3063
|
+
}
|
|
3064
|
+
|
|
2847
3065
|
default:
|
|
2848
3066
|
return { error: 'Unknown tool' };
|
|
2849
3067
|
}
|
|
2850
3068
|
}
|
|
2851
3069
|
|
|
3070
|
+
// ============================================================
|
|
3071
|
+
// ACCOUNTABILITY CHECK - Detect LLM fabrication patterns
|
|
3072
|
+
// ============================================================
|
|
3073
|
+
|
|
3074
|
+
function runAccountabilityCheck(scope, projectRoot) {
|
|
3075
|
+
scope = scope || 'full';
|
|
3076
|
+
projectRoot = projectRoot || '/root';
|
|
3077
|
+
|
|
3078
|
+
var findings = [];
|
|
3079
|
+
var fabrications = 0;
|
|
3080
|
+
|
|
3081
|
+
// CHECK 1: Placeholder credentials next to real ones in backups
|
|
3082
|
+
if (scope === 'full' || scope === 'credentials') {
|
|
3083
|
+
var placeholderPatterns = [
|
|
3084
|
+
'YOUR_', 'CHANGEME', 'TODO:', 'REPLACE_', 'xxx', 'placeholder',
|
|
3085
|
+
'YOUR_WIX_SITE_ID', 'YOUR_WIX_ACCOUNT_ID', 'YOUR_WIX_API_KEY',
|
|
3086
|
+
'YOUR_API_KEY', 'sk-xxx', 'token_here'
|
|
3087
|
+
];
|
|
3088
|
+
|
|
3089
|
+
try {
|
|
3090
|
+
var configs = execSync(
|
|
3091
|
+
'find ' + projectRoot + ' -maxdepth 4 -name "*.json" -o -name "*.env" -o -name "*.config.js" 2>/dev/null | grep -v node_modules | grep -v .pm2',
|
|
3092
|
+
{ encoding: 'utf8', timeout: 10000 }
|
|
3093
|
+
).trim().split('\n').filter(Boolean);
|
|
3094
|
+
|
|
3095
|
+
configs.forEach(function(configFile) {
|
|
3096
|
+
try {
|
|
3097
|
+
var content = fs.readFileSync(configFile, 'utf8');
|
|
3098
|
+
placeholderPatterns.forEach(function(pattern) {
|
|
3099
|
+
if (content.indexOf(pattern) > -1) {
|
|
3100
|
+
var basename = path.basename(configFile);
|
|
3101
|
+
try {
|
|
3102
|
+
var backups = execSync(
|
|
3103
|
+
'find ' + projectRoot + '/911restore ' + projectRoot + '/archive -name "' + basename + '" 2>/dev/null',
|
|
3104
|
+
{ encoding: 'utf8', timeout: 5000 }
|
|
3105
|
+
).trim().split('\n').filter(Boolean);
|
|
3106
|
+
|
|
3107
|
+
backups.forEach(function(backup) {
|
|
3108
|
+
var backupContent = fs.readFileSync(backup, 'utf8');
|
|
3109
|
+
if (backupContent.indexOf(pattern) === -1) {
|
|
3110
|
+
fabrications++;
|
|
3111
|
+
findings.push({
|
|
3112
|
+
type: 'PLACEHOLDER_WITH_REAL_BACKUP',
|
|
3113
|
+
severity: 'HIGH',
|
|
3114
|
+
file: configFile,
|
|
3115
|
+
pattern: pattern,
|
|
3116
|
+
backup: backup,
|
|
3117
|
+
message: 'File has placeholder "' + pattern + '" but backup at ' + backup + ' has real values. Agent likely lost/overwrote credentials instead of restoring them.'
|
|
3118
|
+
});
|
|
3119
|
+
}
|
|
3120
|
+
});
|
|
3121
|
+
} catch(e) {}
|
|
3122
|
+
}
|
|
3123
|
+
});
|
|
3124
|
+
} catch(e) {}
|
|
3125
|
+
});
|
|
3126
|
+
} catch(e) {}
|
|
3127
|
+
}
|
|
3128
|
+
|
|
3129
|
+
// CHECK 2: Recently created files that duplicate existing ones
|
|
3130
|
+
if (scope === 'full' || scope === 'duplicates') {
|
|
3131
|
+
try {
|
|
3132
|
+
var recent = execSync(
|
|
3133
|
+
'find ' + projectRoot + ' -maxdepth 3 -mmin -1440 -type f -name "*.html" -o -name "*.md" -o -name "*.js" 2>/dev/null | grep -v node_modules | grep -v .pm2 | grep -v 911restore',
|
|
3134
|
+
{ encoding: 'utf8', timeout: 10000 }
|
|
3135
|
+
).trim().split('\n').filter(Boolean);
|
|
3136
|
+
|
|
3137
|
+
recent.forEach(function(newFile) {
|
|
3138
|
+
var basename = path.basename(newFile);
|
|
3139
|
+
try {
|
|
3140
|
+
var similar = execSync(
|
|
3141
|
+
'find ' + projectRoot + ' -name "' + basename + '" -not -path "' + newFile + '" -not -path "*/node_modules/*" -not -path "*/911restore/*" 2>/dev/null',
|
|
3142
|
+
{ encoding: 'utf8', timeout: 5000 }
|
|
3143
|
+
).trim().split('\n').filter(Boolean);
|
|
3144
|
+
|
|
3145
|
+
if (similar.length > 0) {
|
|
3146
|
+
findings.push({
|
|
3147
|
+
type: 'POTENTIAL_DUPLICATE',
|
|
3148
|
+
severity: 'MEDIUM',
|
|
3149
|
+
file: newFile,
|
|
3150
|
+
duplicates: similar,
|
|
3151
|
+
message: 'Recently created file has same name as existing: ' + similar.join(', ') + '. Verify this is intentional and not an agent creating a workaround.'
|
|
3152
|
+
});
|
|
3153
|
+
}
|
|
3154
|
+
} catch(e) {}
|
|
3155
|
+
});
|
|
3156
|
+
} catch(e) {}
|
|
3157
|
+
}
|
|
3158
|
+
|
|
3159
|
+
// CHECK 3: Workaround detection
|
|
3160
|
+
if (scope === 'full' || scope === 'workarounds') {
|
|
3161
|
+
var vpsBlog = projectRoot + '/family-home/blog/';
|
|
3162
|
+
if (fs.existsSync(vpsBlog)) {
|
|
3163
|
+
var blogFiles = fs.readdirSync(vpsBlog).filter(function(f) { return f.endsWith('.html') && f !== 'index.html'; });
|
|
3164
|
+
if (blogFiles.length > 0) {
|
|
3165
|
+
try {
|
|
3166
|
+
var publishedContent = JSON.parse(fs.readFileSync(projectRoot + '/family-data/published-content.json', 'utf8'));
|
|
3167
|
+
if (publishedContent.wix_blogs && publishedContent.wix_blogs.length > 0) {
|
|
3168
|
+
findings.push({
|
|
3169
|
+
type: 'DUPLICATE_PURPOSE',
|
|
3170
|
+
severity: 'LOW',
|
|
3171
|
+
file: vpsBlog,
|
|
3172
|
+
message: 'VPS blog has ' + blogFiles.length + ' articles but Wix blog at levelsofself.com already has ' + publishedContent.wix_blogs.length + ' posts. Verify VPS blog is intentional and not an agent-created workaround.'
|
|
3173
|
+
});
|
|
3174
|
+
}
|
|
3175
|
+
} catch(e) {}
|
|
3176
|
+
}
|
|
3177
|
+
}
|
|
3178
|
+
}
|
|
3179
|
+
|
|
3180
|
+
return {
|
|
3181
|
+
status: fabrications > 0 ? 'FABRICATION_DETECTED' : 'clean',
|
|
3182
|
+
fabrications: fabrications,
|
|
3183
|
+
total_findings: findings.length,
|
|
3184
|
+
findings: findings,
|
|
3185
|
+
recommendation: fabrications > 0
|
|
3186
|
+
? 'Agent fabricated ' + fabrications + ' replacement(s) instead of finding existing resources. Restore from backups and add the missing paths to the session handoff so future sessions know where things are.'
|
|
3187
|
+
: 'No fabrication patterns detected.'
|
|
3188
|
+
};
|
|
3189
|
+
}
|
|
3190
|
+
|
|
3191
|
+
// ============================================================
|
|
3192
|
+
// USAGE REPORT - Token usage per bot per day
|
|
3193
|
+
// ============================================================
|
|
3194
|
+
|
|
3195
|
+
function runUsageReport(days) {
|
|
3196
|
+
try {
|
|
3197
|
+
var usage = JSON.parse(fs.readFileSync('/root/family-data/api-usage.json', 'utf8'));
|
|
3198
|
+
days = days || 3;
|
|
3199
|
+
var dates = Object.keys(usage.daily || {}).sort().slice(-days);
|
|
3200
|
+
var report = 'TOKEN USAGE REPORT\n==================\n\n';
|
|
3201
|
+
|
|
3202
|
+
dates.forEach(function(date) {
|
|
3203
|
+
var day = usage.daily[date];
|
|
3204
|
+
var bots = day.byBot || {};
|
|
3205
|
+
var totalCalls = day.totalCalls || 0;
|
|
3206
|
+
var totalPrompt = 0;
|
|
3207
|
+
|
|
3208
|
+
report += date + ' - ' + totalCalls + ' total calls\n';
|
|
3209
|
+
|
|
3210
|
+
var botList = Object.keys(bots).map(function(name) {
|
|
3211
|
+
var b = bots[name];
|
|
3212
|
+
var prompt = b.promptTokensEst || 0;
|
|
3213
|
+
totalPrompt += prompt;
|
|
3214
|
+
var calls = b.calls || 0;
|
|
3215
|
+
var avg = calls > 0 ? Math.round(prompt / calls) : 0;
|
|
3216
|
+
var claude = (b.providers || {}).claude || (b.providers || {}).cli || 0;
|
|
3217
|
+
return { name: name, prompt: prompt, calls: calls, avg: avg, claude: claude };
|
|
3218
|
+
}).sort(function(a, b) { return b.prompt - a.prompt; });
|
|
3219
|
+
|
|
3220
|
+
botList.forEach(function(b) {
|
|
3221
|
+
var flag = b.prompt > 1000000 ? ' *** HIGH ***' : (b.avg > 50000 ? ' * WARN *' : '');
|
|
3222
|
+
report += ' ' + b.name + ': ' + b.calls + ' calls, ' + Math.round(b.prompt/1000) + 'K prompt tokens, avg ' + Math.round(b.avg/1000) + 'K/call, Claude: ' + b.claude + flag + '\n';
|
|
3223
|
+
});
|
|
3224
|
+
|
|
3225
|
+
report += ' TOTAL: ' + Math.round(totalPrompt/1000) + 'K prompt tokens\n\n';
|
|
3226
|
+
});
|
|
3227
|
+
|
|
3228
|
+
// Alerts
|
|
3229
|
+
var today = new Date().toISOString().split('T')[0];
|
|
3230
|
+
var todayData = (usage.daily || {})[today] || {};
|
|
3231
|
+
var todayBots = todayData.byBot || {};
|
|
3232
|
+
var alerts = [];
|
|
3233
|
+
Object.keys(todayBots).forEach(function(name) {
|
|
3234
|
+
var b = todayBots[name];
|
|
3235
|
+
var prompt = b.promptTokensEst || 0;
|
|
3236
|
+
var calls = b.calls || 0;
|
|
3237
|
+
var avg = calls > 0 ? Math.round(prompt / calls) : 0;
|
|
3238
|
+
if (prompt > 5000000) alerts.push('CRITICAL: ' + name + ' at ' + Math.round(prompt/1000000) + 'M tokens today');
|
|
3239
|
+
else if (prompt > 1000000) alerts.push('WARNING: ' + name + ' at ' + Math.round(prompt/1000) + 'K tokens today');
|
|
3240
|
+
if (avg > 50000 && calls > 3) alerts.push('BLOAT: ' + name + ' averaging ' + Math.round(avg/1000) + 'K tokens/call - check knowledge file');
|
|
3241
|
+
});
|
|
3242
|
+
|
|
3243
|
+
if (alerts.length > 0) {
|
|
3244
|
+
report += 'ALERTS:\n';
|
|
3245
|
+
alerts.forEach(function(a) { report += ' ' + a + '\n'; });
|
|
3246
|
+
} else {
|
|
3247
|
+
report += 'No alerts. All bots within normal range.\n';
|
|
3248
|
+
}
|
|
3249
|
+
|
|
3250
|
+
return report;
|
|
3251
|
+
} catch(e) {
|
|
3252
|
+
return 'Error reading usage: ' + e.message;
|
|
3253
|
+
}
|
|
3254
|
+
}
|
|
3255
|
+
|
|
2852
3256
|
// ============================================================
|
|
2853
3257
|
// ============================================================
|
|
2854
3258
|
// SELF-CHECK - Catches issues before Arthur has to
|
|
@@ -3636,7 +4040,7 @@ const server = http.createServer((req, res) => {
|
|
|
3636
4040
|
// Health check
|
|
3637
4041
|
if (req.method === 'GET' && url.pathname === '/health') {
|
|
3638
4042
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
3639
|
-
res.end(JSON.stringify({ status: 'ok', service: 'nervous-system-mcp', version: '1.
|
|
4043
|
+
res.end(JSON.stringify({ status: 'ok', service: 'nervous-system-mcp', version: '1.10.0', protocol: MCP_VERSION }));
|
|
3640
4044
|
return;
|
|
3641
4045
|
}
|
|
3642
4046
|
|
|
@@ -3753,7 +4157,7 @@ const server = http.createServer((req, res) => {
|
|
|
3753
4157
|
res.writeHead(200, { 'Content-Type': 'application/json' });
|
|
3754
4158
|
res.end(JSON.stringify({
|
|
3755
4159
|
name: 'The Nervous System MCP Server',
|
|
3756
|
-
version: '1.
|
|
4160
|
+
version: '1.10.0',
|
|
3757
4161
|
protocol: MCP_VERSION,
|
|
3758
4162
|
description: 'LLM behavioral enforcement framework. 7 core rules, preflight checks, session handoffs, worklogs, violation logging, kill switch, hash-chained audit, and forced reflection cycles. Built by Arthur Palyan.',
|
|
3759
4163
|
endpoints: {
|
|
@@ -3775,7 +4179,7 @@ const server = http.createServer((req, res) => {
|
|
|
3775
4179
|
migrateExistingViolations();
|
|
3776
4180
|
|
|
3777
4181
|
server.listen(PORT, '127.0.0.1', () => {
|
|
3778
|
-
console.error(`[MCP Server] Nervous System v1.
|
|
4182
|
+
console.error(`[MCP Server] Nervous System v1.10.0 running on port ${PORT}`);
|
|
3779
4183
|
console.error(`[MCP Server] SSE: /sse | HTTP: /mcp | Health: /health | Kill: POST /kill | Audit: GET /audit/verify | Dispatches: GET /dispatches`);
|
|
3780
4184
|
console.error(`[MCP Server] Protocol: ${MCP_VERSION}`);
|
|
3781
4185
|
console.error(`[MCP Server] Tools: ${TOOLS.length} (including kill switch, audit chain, dispatch, drift audit, page health, pre-publish audit)`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-nervous-system",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"description": "Governance layer for multi-agent AI systems. 7 mechanically enforced rules, 30 tools including kill switch, audit chain, dispatch, drift audit, security audit, page health, pre-publish audit, and session close. Works with Ruflo, Hivemind, Agent Teams, and any MCP client.",
|
|
5
5
|
"main": "server.js",
|
|
6
6
|
"bin": {
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "mcp-nervous-system",
|
|
3
|
-
"version": "1.5.1",
|
|
4
|
-
"description": "The Nervous System - LLM Behavioral Enforcement Framework. 7 mechanically enforced rules, 16 tools including kill switch, audit chain, dispatch, drift audit, security audit, page health, and session close. MCP server for Claude Desktop, Claude Code, and any MCP-compatible client.",
|
|
5
|
-
"main": "server.js",
|
|
6
|
-
"bin": {
|
|
7
|
-
"mcp-nervous-system": "./stdio.js"
|
|
8
|
-
},
|
|
9
|
-
"scripts": {
|
|
10
|
-
"start": "node server.js"
|
|
11
|
-
},
|
|
12
|
-
"keywords": [
|
|
13
|
-
"mcp",
|
|
14
|
-
"model-context-protocol",
|
|
15
|
-
"llm",
|
|
16
|
-
"ai-safety",
|
|
17
|
-
"ai-governance",
|
|
18
|
-
"behavioral-enforcement",
|
|
19
|
-
"guardrails",
|
|
20
|
-
"claude",
|
|
21
|
-
"anthropic",
|
|
22
|
-
"nervous-system",
|
|
23
|
-
"kill-switch",
|
|
24
|
-
"audit-trail"
|
|
25
|
-
],
|
|
26
|
-
"author": "Arthur Palyan <palyanai@gmail.com>",
|
|
27
|
-
"license": "MIT",
|
|
28
|
-
"repository": {
|
|
29
|
-
"type": "git",
|
|
30
|
-
"url": "https://github.com/levelsofself/mcp-nervous-system"
|
|
31
|
-
},
|
|
32
|
-
"homepage": "https://api.100levelup.com/family/gateway.html",
|
|
33
|
-
"bugs": {
|
|
34
|
-
"url": "https://github.com/levelsofself/mcp-nervous-system/issues"
|
|
35
|
-
},
|
|
36
|
-
"engines": {
|
|
37
|
-
"node": ">=18.0.0"
|
|
38
|
-
},
|
|
39
|
-
"dependencies": {
|
|
40
|
-
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
41
|
-
}
|
|
42
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "mcp-nervous-system",
|
|
3
|
-
"version": "1.5.0",
|
|
4
|
-
"description": "The Nervous System - LLM Behavioral Enforcement Framework. 7 mechanically enforced rules, 16 tools including kill switch, audit chain, dispatch, drift audit, security audit, page health, and session close. MCP server for Claude Desktop, Claude Code, and any MCP-compatible client.",
|
|
5
|
-
"main": "server.js",
|
|
6
|
-
"bin": {
|
|
7
|
-
"mcp-nervous-system": "./stdio.js"
|
|
8
|
-
},
|
|
9
|
-
"scripts": {
|
|
10
|
-
"start": "node server.js"
|
|
11
|
-
},
|
|
12
|
-
"keywords": [
|
|
13
|
-
"mcp",
|
|
14
|
-
"model-context-protocol",
|
|
15
|
-
"llm",
|
|
16
|
-
"ai-safety",
|
|
17
|
-
"ai-governance",
|
|
18
|
-
"behavioral-enforcement",
|
|
19
|
-
"guardrails",
|
|
20
|
-
"claude",
|
|
21
|
-
"anthropic",
|
|
22
|
-
"nervous-system",
|
|
23
|
-
"kill-switch",
|
|
24
|
-
"audit-trail"
|
|
25
|
-
],
|
|
26
|
-
"author": "Arthur Palyan <palyanai@gmail.com>",
|
|
27
|
-
"license": "MIT",
|
|
28
|
-
"repository": {
|
|
29
|
-
"type": "git",
|
|
30
|
-
"url": "https://github.com/levelsofself/mcp-nervous-system"
|
|
31
|
-
},
|
|
32
|
-
"homepage": "https://api.100levelup.com/family/gateway.html",
|
|
33
|
-
"bugs": {
|
|
34
|
-
"url": "https://github.com/levelsofself/mcp-nervous-system/issues"
|
|
35
|
-
},
|
|
36
|
-
"engines": {
|
|
37
|
-
"node": ">=18.0.0"
|
|
38
|
-
},
|
|
39
|
-
"dependencies": {
|
|
40
|
-
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
41
|
-
}
|
|
42
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "mcp-nervous-system",
|
|
3
|
-
"version": "1.6.0",
|
|
4
|
-
"description": "The Nervous System - LLM Behavioral Enforcement Framework. 7 mechanically enforced rules, 17 tools including kill switch, audit chain, dispatch, drift audit, security audit, page health, pre-publish audit, and session close. MCP server for Claude Desktop, Claude Code, and any MCP-compatible client.",
|
|
5
|
-
"main": "server.js",
|
|
6
|
-
"bin": {
|
|
7
|
-
"mcp-nervous-system": "./stdio.js"
|
|
8
|
-
},
|
|
9
|
-
"scripts": {
|
|
10
|
-
"start": "node server.js"
|
|
11
|
-
},
|
|
12
|
-
"keywords": [
|
|
13
|
-
"mcp",
|
|
14
|
-
"model-context-protocol",
|
|
15
|
-
"llm",
|
|
16
|
-
"ai-safety",
|
|
17
|
-
"ai-governance",
|
|
18
|
-
"behavioral-enforcement",
|
|
19
|
-
"guardrails",
|
|
20
|
-
"claude",
|
|
21
|
-
"anthropic",
|
|
22
|
-
"nervous-system",
|
|
23
|
-
"kill-switch",
|
|
24
|
-
"audit-trail"
|
|
25
|
-
],
|
|
26
|
-
"author": "Arthur Palyan <palyanai@gmail.com>",
|
|
27
|
-
"license": "MIT",
|
|
28
|
-
"repository": {
|
|
29
|
-
"type": "git",
|
|
30
|
-
"url": "https://github.com/levelsofself/mcp-nervous-system"
|
|
31
|
-
},
|
|
32
|
-
"homepage": "https://api.100levelup.com/family/gateway.html",
|
|
33
|
-
"bugs": {
|
|
34
|
-
"url": "https://github.com/levelsofself/mcp-nervous-system/issues"
|
|
35
|
-
},
|
|
36
|
-
"engines": {
|
|
37
|
-
"node": ">=18.0.0"
|
|
38
|
-
},
|
|
39
|
-
"dependencies": {
|
|
40
|
-
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
41
|
-
}
|
|
42
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "mcp-nervous-system",
|
|
3
|
-
"version": "1.7.3",
|
|
4
|
-
"description": "The Nervous System - LLM Behavioral Enforcement Framework. 7 mechanically enforced rules, 17 tools including kill switch, audit chain, dispatch, drift audit, security audit, page health, pre-publish audit, and session close. MCP server for Claude Desktop, Claude Code, and any MCP-compatible client.",
|
|
5
|
-
"main": "server.js",
|
|
6
|
-
"bin": {
|
|
7
|
-
"mcp-nervous-system": "./stdio.js"
|
|
8
|
-
},
|
|
9
|
-
"scripts": {
|
|
10
|
-
"start": "node server.js"
|
|
11
|
-
},
|
|
12
|
-
"keywords": [
|
|
13
|
-
"mcp",
|
|
14
|
-
"model-context-protocol",
|
|
15
|
-
"llm",
|
|
16
|
-
"ai-safety",
|
|
17
|
-
"ai-governance",
|
|
18
|
-
"behavioral-enforcement",
|
|
19
|
-
"guardrails",
|
|
20
|
-
"claude",
|
|
21
|
-
"anthropic",
|
|
22
|
-
"nervous-system",
|
|
23
|
-
"kill-switch",
|
|
24
|
-
"audit-trail"
|
|
25
|
-
],
|
|
26
|
-
"author": "Arthur Palyan <palyanai@gmail.com>",
|
|
27
|
-
"license": "MIT",
|
|
28
|
-
"repository": {
|
|
29
|
-
"type": "git",
|
|
30
|
-
"url": "https://github.com/levelsofself/mcp-nervous-system"
|
|
31
|
-
},
|
|
32
|
-
"homepage": "https://api.100levelup.com/family/gateway.html",
|
|
33
|
-
"bugs": {
|
|
34
|
-
"url": "https://github.com/levelsofself/mcp-nervous-system/issues"
|
|
35
|
-
},
|
|
36
|
-
"engines": {
|
|
37
|
-
"node": ">=18.0.0"
|
|
38
|
-
},
|
|
39
|
-
"dependencies": {
|
|
40
|
-
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
41
|
-
}
|
|
42
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "mcp-nervous-system",
|
|
3
|
-
"version": "1.7.2",
|
|
4
|
-
"description": "The Nervous System - LLM Behavioral Enforcement Framework. 7 mechanically enforced rules, 17 tools including kill switch, audit chain, dispatch, drift audit, security audit, page health, pre-publish audit, and session close. MCP server for Claude Desktop, Claude Code, and any MCP-compatible client.",
|
|
5
|
-
"main": "server.js",
|
|
6
|
-
"bin": {
|
|
7
|
-
"mcp-nervous-system": "./stdio.js"
|
|
8
|
-
},
|
|
9
|
-
"scripts": {
|
|
10
|
-
"start": "node server.js"
|
|
11
|
-
},
|
|
12
|
-
"keywords": [
|
|
13
|
-
"mcp",
|
|
14
|
-
"model-context-protocol",
|
|
15
|
-
"llm",
|
|
16
|
-
"ai-safety",
|
|
17
|
-
"ai-governance",
|
|
18
|
-
"behavioral-enforcement",
|
|
19
|
-
"guardrails",
|
|
20
|
-
"claude",
|
|
21
|
-
"anthropic",
|
|
22
|
-
"nervous-system",
|
|
23
|
-
"kill-switch",
|
|
24
|
-
"audit-trail"
|
|
25
|
-
],
|
|
26
|
-
"author": "Arthur Palyan <palyanai@gmail.com>",
|
|
27
|
-
"license": "MIT",
|
|
28
|
-
"repository": {
|
|
29
|
-
"type": "git",
|
|
30
|
-
"url": "https://github.com/levelsofself/mcp-nervous-system"
|
|
31
|
-
},
|
|
32
|
-
"homepage": "https://api.100levelup.com/family/gateway.html",
|
|
33
|
-
"bugs": {
|
|
34
|
-
"url": "https://github.com/levelsofself/mcp-nervous-system/issues"
|
|
35
|
-
},
|
|
36
|
-
"engines": {
|
|
37
|
-
"node": ">=18.0.0"
|
|
38
|
-
},
|
|
39
|
-
"dependencies": {
|
|
40
|
-
"@modelcontextprotocol/sdk": "^1.0.0"
|
|
41
|
-
}
|
|
42
|
-
}
|