@darkiceinteractive/mcp-conductor 1.0.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.
Files changed (125) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +558 -0
  3. package/dist/bin/cli.d.ts +8 -0
  4. package/dist/bin/cli.d.ts.map +1 -0
  5. package/dist/bin/cli.js +940 -0
  6. package/dist/bin/cli.js.map +1 -0
  7. package/dist/bridge/http-server.d.ts +161 -0
  8. package/dist/bridge/http-server.d.ts.map +1 -0
  9. package/dist/bridge/http-server.js +367 -0
  10. package/dist/bridge/http-server.js.map +1 -0
  11. package/dist/bridge/index.d.ts +5 -0
  12. package/dist/bridge/index.d.ts.map +1 -0
  13. package/dist/bridge/index.js +5 -0
  14. package/dist/bridge/index.js.map +1 -0
  15. package/dist/config/defaults.d.ts +29 -0
  16. package/dist/config/defaults.d.ts.map +1 -0
  17. package/dist/config/defaults.js +60 -0
  18. package/dist/config/defaults.js.map +1 -0
  19. package/dist/config/index.d.ts +7 -0
  20. package/dist/config/index.d.ts.map +1 -0
  21. package/dist/config/index.js +7 -0
  22. package/dist/config/index.js.map +1 -0
  23. package/dist/config/loader.d.ts +49 -0
  24. package/dist/config/loader.d.ts.map +1 -0
  25. package/dist/config/loader.js +272 -0
  26. package/dist/config/loader.js.map +1 -0
  27. package/dist/config/schema.d.ts +93 -0
  28. package/dist/config/schema.d.ts.map +1 -0
  29. package/dist/config/schema.js +5 -0
  30. package/dist/config/schema.js.map +1 -0
  31. package/dist/hub/index.d.ts +5 -0
  32. package/dist/hub/index.d.ts.map +1 -0
  33. package/dist/hub/index.js +5 -0
  34. package/dist/hub/index.js.map +1 -0
  35. package/dist/hub/mcp-hub.d.ts +176 -0
  36. package/dist/hub/mcp-hub.d.ts.map +1 -0
  37. package/dist/hub/mcp-hub.js +550 -0
  38. package/dist/hub/mcp-hub.js.map +1 -0
  39. package/dist/index.d.ts +9 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +45 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/metrics/index.d.ts +5 -0
  44. package/dist/metrics/index.d.ts.map +1 -0
  45. package/dist/metrics/index.js +5 -0
  46. package/dist/metrics/index.js.map +1 -0
  47. package/dist/metrics/metrics-collector.d.ts +211 -0
  48. package/dist/metrics/metrics-collector.d.ts.map +1 -0
  49. package/dist/metrics/metrics-collector.js +437 -0
  50. package/dist/metrics/metrics-collector.js.map +1 -0
  51. package/dist/modes/index.d.ts +5 -0
  52. package/dist/modes/index.d.ts.map +1 -0
  53. package/dist/modes/index.js +5 -0
  54. package/dist/modes/index.js.map +1 -0
  55. package/dist/modes/mode-handler.d.ts +132 -0
  56. package/dist/modes/mode-handler.d.ts.map +1 -0
  57. package/dist/modes/mode-handler.js +252 -0
  58. package/dist/modes/mode-handler.js.map +1 -0
  59. package/dist/runtime/executor.d.ts +57 -0
  60. package/dist/runtime/executor.d.ts.map +1 -0
  61. package/dist/runtime/executor.js +700 -0
  62. package/dist/runtime/executor.js.map +1 -0
  63. package/dist/runtime/index.d.ts +5 -0
  64. package/dist/runtime/index.d.ts.map +1 -0
  65. package/dist/runtime/index.js +5 -0
  66. package/dist/runtime/index.js.map +1 -0
  67. package/dist/server/index.d.ts +5 -0
  68. package/dist/server/index.d.ts.map +1 -0
  69. package/dist/server/index.js +5 -0
  70. package/dist/server/index.js.map +1 -0
  71. package/dist/server/mcp-server.d.ts +62 -0
  72. package/dist/server/mcp-server.d.ts.map +1 -0
  73. package/dist/server/mcp-server.js +1272 -0
  74. package/dist/server/mcp-server.js.map +1 -0
  75. package/dist/skills/index.d.ts +5 -0
  76. package/dist/skills/index.d.ts.map +1 -0
  77. package/dist/skills/index.js +5 -0
  78. package/dist/skills/index.js.map +1 -0
  79. package/dist/skills/skills-engine.d.ts +157 -0
  80. package/dist/skills/skills-engine.d.ts.map +1 -0
  81. package/dist/skills/skills-engine.js +405 -0
  82. package/dist/skills/skills-engine.js.map +1 -0
  83. package/dist/streaming/execution-stream.d.ts +158 -0
  84. package/dist/streaming/execution-stream.d.ts.map +1 -0
  85. package/dist/streaming/execution-stream.js +320 -0
  86. package/dist/streaming/execution-stream.js.map +1 -0
  87. package/dist/streaming/index.d.ts +5 -0
  88. package/dist/streaming/index.d.ts.map +1 -0
  89. package/dist/streaming/index.js +5 -0
  90. package/dist/streaming/index.js.map +1 -0
  91. package/dist/utils/errors.d.ts +36 -0
  92. package/dist/utils/errors.d.ts.map +1 -0
  93. package/dist/utils/errors.js +68 -0
  94. package/dist/utils/errors.js.map +1 -0
  95. package/dist/utils/helpers.d.ts +44 -0
  96. package/dist/utils/helpers.d.ts.map +1 -0
  97. package/dist/utils/helpers.js +95 -0
  98. package/dist/utils/helpers.js.map +1 -0
  99. package/dist/utils/index.d.ts +9 -0
  100. package/dist/utils/index.d.ts.map +1 -0
  101. package/dist/utils/index.js +9 -0
  102. package/dist/utils/index.js.map +1 -0
  103. package/dist/utils/logger.d.ts +13 -0
  104. package/dist/utils/logger.d.ts.map +1 -0
  105. package/dist/utils/logger.js +48 -0
  106. package/dist/utils/logger.js.map +1 -0
  107. package/dist/utils/permissions.d.ts +97 -0
  108. package/dist/utils/permissions.d.ts.map +1 -0
  109. package/dist/utils/permissions.js +165 -0
  110. package/dist/utils/permissions.js.map +1 -0
  111. package/dist/utils/rate-limiter.d.ts +87 -0
  112. package/dist/utils/rate-limiter.d.ts.map +1 -0
  113. package/dist/utils/rate-limiter.js +187 -0
  114. package/dist/utils/rate-limiter.js.map +1 -0
  115. package/dist/watcher/config-watcher.d.ts +67 -0
  116. package/dist/watcher/config-watcher.d.ts.map +1 -0
  117. package/dist/watcher/config-watcher.js +150 -0
  118. package/dist/watcher/config-watcher.js.map +1 -0
  119. package/dist/watcher/index.d.ts +5 -0
  120. package/dist/watcher/index.d.ts.map +1 -0
  121. package/dist/watcher/index.js +5 -0
  122. package/dist/watcher/index.js.map +1 -0
  123. package/package.json +86 -0
  124. package/templates/CLAUDE.md +137 -0
  125. package/templates/skill-mcp-conductor.md +64 -0
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Miscellaneous helper utilities
3
+ */
4
+ /**
5
+ * Generate a unique execution ID
6
+ */
7
+ export declare function generateExecutionId(): string;
8
+ /**
9
+ * Estimate token count from text (rough approximation: ~4 chars per token)
10
+ */
11
+ export declare function estimateTokens(text: string): number;
12
+ /**
13
+ * Estimate token count from byte size
14
+ */
15
+ export declare function estimateTokensFromBytes(bytes: number): number;
16
+ /**
17
+ * Calculate percentage change
18
+ */
19
+ export declare function percentageChange(original: number, newValue: number): string;
20
+ /**
21
+ * Format bytes to human readable string
22
+ */
23
+ export declare function formatBytes(bytes: number): string;
24
+ /**
25
+ * Format milliseconds to human readable duration
26
+ */
27
+ export declare function formatDuration(ms: number): string;
28
+ /**
29
+ * Debounce function calls
30
+ */
31
+ export declare function debounce<T extends (...args: unknown[]) => unknown>(func: T, waitMs: number): (...args: Parameters<T>) => void;
32
+ /**
33
+ * Sleep for a given duration
34
+ */
35
+ export declare function sleep(ms: number): Promise<void>;
36
+ /**
37
+ * Safely parse JSON with a fallback
38
+ */
39
+ export declare function safeJsonParse<T>(json: string, fallback: T): T;
40
+ /**
41
+ * Truncate string to max length with ellipsis
42
+ */
43
+ export declare function truncate(str: string, maxLength: number): string;
44
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAK3E;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,EAChE,IAAI,EAAE,CAAC,EACP,MAAM,EAAE,MAAM,GACb,CAAC,GAAG,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,IAAI,CAWlC;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAM7D;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAG/D"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Miscellaneous helper utilities
3
+ */
4
+ import { v4 as uuidv4 } from 'uuid';
5
+ /**
6
+ * Generate a unique execution ID
7
+ */
8
+ export function generateExecutionId() {
9
+ return uuidv4();
10
+ }
11
+ /**
12
+ * Estimate token count from text (rough approximation: ~4 chars per token)
13
+ */
14
+ export function estimateTokens(text) {
15
+ return Math.ceil(text.length / 4);
16
+ }
17
+ /**
18
+ * Estimate token count from byte size
19
+ */
20
+ export function estimateTokensFromBytes(bytes) {
21
+ return Math.ceil(bytes / 4);
22
+ }
23
+ /**
24
+ * Calculate percentage change
25
+ */
26
+ export function percentageChange(original, newValue) {
27
+ if (original === 0)
28
+ return newValue === 0 ? '0%' : '+∞%';
29
+ const change = ((newValue - original) / original) * 100;
30
+ const sign = change >= 0 ? '+' : '';
31
+ return `${sign}${change.toFixed(1)}%`;
32
+ }
33
+ /**
34
+ * Format bytes to human readable string
35
+ */
36
+ export function formatBytes(bytes) {
37
+ if (bytes === 0)
38
+ return '0 B';
39
+ const k = 1024;
40
+ const sizes = ['B', 'KB', 'MB', 'GB'];
41
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
42
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`;
43
+ }
44
+ /**
45
+ * Format milliseconds to human readable duration
46
+ */
47
+ export function formatDuration(ms) {
48
+ if (ms < 1000)
49
+ return `${ms}ms`;
50
+ if (ms < 60000)
51
+ return `${(ms / 1000).toFixed(2)}s`;
52
+ const minutes = Math.floor(ms / 60000);
53
+ const seconds = ((ms % 60000) / 1000).toFixed(0);
54
+ return `${minutes}m ${seconds}s`;
55
+ }
56
+ /**
57
+ * Debounce function calls
58
+ */
59
+ export function debounce(func, waitMs) {
60
+ let timeout = null;
61
+ return (...args) => {
62
+ if (timeout) {
63
+ clearTimeout(timeout);
64
+ }
65
+ timeout = setTimeout(() => {
66
+ func(...args);
67
+ }, waitMs);
68
+ };
69
+ }
70
+ /**
71
+ * Sleep for a given duration
72
+ */
73
+ export function sleep(ms) {
74
+ return new Promise((resolve) => setTimeout(resolve, ms));
75
+ }
76
+ /**
77
+ * Safely parse JSON with a fallback
78
+ */
79
+ export function safeJsonParse(json, fallback) {
80
+ try {
81
+ return JSON.parse(json);
82
+ }
83
+ catch {
84
+ return fallback;
85
+ }
86
+ }
87
+ /**
88
+ * Truncate string to max length with ellipsis
89
+ */
90
+ export function truncate(str, maxLength) {
91
+ if (str.length <= maxLength)
92
+ return str;
93
+ return str.slice(0, maxLength - 3) + '...';
94
+ }
95
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Utils module exports
3
+ */
4
+ export * from './logger.js';
5
+ export * from './errors.js';
6
+ export * from './helpers.js';
7
+ export * from './permissions.js';
8
+ export * from './rate-limiter.js';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Utils module exports
3
+ */
4
+ export * from './logger.js';
5
+ export * from './errors.js';
6
+ export * from './helpers.js';
7
+ export * from './permissions.js';
8
+ export * from './rate-limiter.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Simple logger utility for MCP Executor
3
+ */
4
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
5
+ export declare const logger: {
6
+ setLevel(level: LogLevel): void;
7
+ getLevel(): LogLevel;
8
+ debug(message: string, meta?: Record<string, unknown>): void;
9
+ info(message: string, meta?: Record<string, unknown>): void;
10
+ warn(message: string, meta?: Record<string, unknown>): void;
11
+ error(message: string, meta?: Record<string, unknown>): void;
12
+ };
13
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAsB3D,eAAO,MAAM,MAAM;oBACD,QAAQ,GAAG,IAAI;gBAInB,QAAQ;mBAIL,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;kBAM9C,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;kBAM7C,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;mBAM5C,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAK7D,CAAC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Simple logger utility for MCP Executor
3
+ */
4
+ const LOG_LEVELS = {
5
+ debug: 0,
6
+ info: 1,
7
+ warn: 2,
8
+ error: 3,
9
+ };
10
+ let currentLevel = process.env['MCP_EXECUTOR_LOG_LEVEL'] || 'info';
11
+ function shouldLog(level) {
12
+ return LOG_LEVELS[level] >= LOG_LEVELS[currentLevel];
13
+ }
14
+ function formatMessage(level, message, meta) {
15
+ const timestamp = new Date().toISOString();
16
+ const prefix = `[${timestamp}] [${level.toUpperCase()}]`;
17
+ const metaStr = meta ? ` ${JSON.stringify(meta)}` : '';
18
+ return `${prefix} ${message}${metaStr}`;
19
+ }
20
+ export const logger = {
21
+ setLevel(level) {
22
+ currentLevel = level;
23
+ },
24
+ getLevel() {
25
+ return currentLevel;
26
+ },
27
+ debug(message, meta) {
28
+ if (shouldLog('debug')) {
29
+ console.error(formatMessage('debug', message, meta));
30
+ }
31
+ },
32
+ info(message, meta) {
33
+ if (shouldLog('info')) {
34
+ console.error(formatMessage('info', message, meta));
35
+ }
36
+ },
37
+ warn(message, meta) {
38
+ if (shouldLog('warn')) {
39
+ console.error(formatMessage('warn', message, meta));
40
+ }
41
+ },
42
+ error(message, meta) {
43
+ if (shouldLog('error')) {
44
+ console.error(formatMessage('error', message, meta));
45
+ }
46
+ },
47
+ };
48
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,UAAU,GAA6B;IAC3C,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;CACT,CAAC;AAEF,IAAI,YAAY,GAAc,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAc,IAAI,MAAM,CAAC;AAE3F,SAAS,SAAS,CAAC,KAAe;IAChC,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC;AACvD,CAAC;AAED,SAAS,aAAa,CAAC,KAAe,EAAE,OAAe,EAAE,IAA8B;IACrF,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,MAAM,MAAM,GAAG,IAAI,SAAS,MAAM,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC;IACzD,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACvD,OAAO,GAAG,MAAM,IAAI,OAAO,GAAG,OAAO,EAAE,CAAC;AAC1C,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,QAAQ,CAAC,KAAe;QACtB,YAAY,GAAG,KAAK,CAAC;IACvB,CAAC;IAED,QAAQ;QACN,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,IAA8B;QACnD,IAAI,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,IAA8B;QAClD,IAAI,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,IAA8B;QAClD,IAAI,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,IAA8B;QACnD,IAAI,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Permissions utility for managing Claude Code MCP tool permissions
3
+ *
4
+ * This utility helps generate permission entries for MCP tools
5
+ * and can update Claude's settings.json files.
6
+ */
7
+ /**
8
+ * Claude settings file structure
9
+ */
10
+ export interface ClaudeSettings {
11
+ permissions?: {
12
+ allow?: string[];
13
+ deny?: string[];
14
+ ask?: string[];
15
+ };
16
+ [key: string]: unknown;
17
+ }
18
+ /**
19
+ * Permission entry with metadata
20
+ */
21
+ export interface PermissionEntry {
22
+ permission: string;
23
+ server: string;
24
+ tool: string;
25
+ }
26
+ /**
27
+ * Result of permission generation
28
+ */
29
+ export interface PermissionGenerationResult {
30
+ all: PermissionEntry[];
31
+ new: PermissionEntry[];
32
+ existing: PermissionEntry[];
33
+ }
34
+ /**
35
+ * Settings scope for where to save permissions
36
+ */
37
+ export type SettingsScope = 'user' | 'project';
38
+ /**
39
+ * Get the path to Claude's user settings.json
40
+ */
41
+ export declare function getUserSettingsPath(): string;
42
+ /**
43
+ * Get the path to project-level settings.json
44
+ */
45
+ export declare function getProjectSettingsPath(): string;
46
+ /**
47
+ * Get settings file path based on scope
48
+ */
49
+ export declare function getSettingsPath(scope: SettingsScope): string;
50
+ /**
51
+ * Generate permission string for an MCP tool
52
+ * Format: mcp__<server-name>__<tool-name>
53
+ */
54
+ export declare function generatePermissionString(serverName: string, toolName: string): string;
55
+ /**
56
+ * Parse a permission string into its components
57
+ */
58
+ export declare function parsePermissionString(permission: string): {
59
+ server: string;
60
+ tool: string;
61
+ } | null;
62
+ /**
63
+ * Load Claude settings from a file
64
+ */
65
+ export declare function loadClaudeSettings(path: string): ClaudeSettings | null;
66
+ /**
67
+ * Save Claude settings to a file
68
+ */
69
+ export declare function saveClaudeSettings(path: string, settings: ClaudeSettings): boolean;
70
+ /**
71
+ * Get existing MCP permissions from settings
72
+ */
73
+ export declare function getExistingPermissions(settings: ClaudeSettings): Set<string>;
74
+ /**
75
+ * Generate permission entries from server/tool list
76
+ */
77
+ export declare function generatePermissionEntries(tools: Array<{
78
+ server: string;
79
+ tool: string;
80
+ }>): PermissionEntry[];
81
+ /**
82
+ * Compare generated permissions against existing ones
83
+ */
84
+ export declare function comparePermissions(generated: PermissionEntry[], existing: Set<string>): PermissionGenerationResult;
85
+ /**
86
+ * Add permissions to settings
87
+ */
88
+ export declare function addPermissionsToSettings(settings: ClaudeSettings, permissions: string[]): ClaudeSettings;
89
+ /**
90
+ * Format permissions for display
91
+ */
92
+ export declare function formatPermissionsForDisplay(entries: PermissionEntry[]): string;
93
+ /**
94
+ * Generate JSON array of permission strings for copying
95
+ */
96
+ export declare function formatPermissionsAsJson(entries: PermissionEntry[]): string;
97
+ //# sourceMappingURL=permissions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/utils/permissions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,CAAC,EAAE;QACZ,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;KAChB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,GAAG,EAAE,eAAe,EAAE,CAAC;IACvB,GAAG,EAAE,eAAe,EAAE,CAAC;IACvB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,CAAC;AAE/C;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAE5D;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAErF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAIjG;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAYtE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,OAAO,CAelF;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,cAAc,GAAG,GAAG,CAAC,MAAM,CAAC,CAW5E;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAC7C,eAAe,EAAE,CAMnB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,eAAe,EAAE,EAC5B,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,GACpB,0BAA0B,CAiB5B;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,cAAc,EACxB,WAAW,EAAE,MAAM,EAAE,GACpB,cAAc,CAgBhB;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAkB9E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAG1E"}
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Permissions utility for managing Claude Code MCP tool permissions
3
+ *
4
+ * This utility helps generate permission entries for MCP tools
5
+ * and can update Claude's settings.json files.
6
+ */
7
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
8
+ import { homedir } from 'node:os';
9
+ import { join } from 'node:path';
10
+ import { logger, safeJsonParse } from './index.js';
11
+ /**
12
+ * Get the path to Claude's user settings.json
13
+ */
14
+ export function getUserSettingsPath() {
15
+ return join(homedir(), '.claude', 'settings.json');
16
+ }
17
+ /**
18
+ * Get the path to project-level settings.json
19
+ */
20
+ export function getProjectSettingsPath() {
21
+ return join(process.cwd(), '.claude', 'settings.json');
22
+ }
23
+ /**
24
+ * Get settings file path based on scope
25
+ */
26
+ export function getSettingsPath(scope) {
27
+ return scope === 'user' ? getUserSettingsPath() : getProjectSettingsPath();
28
+ }
29
+ /**
30
+ * Generate permission string for an MCP tool
31
+ * Format: mcp__<server-name>__<tool-name>
32
+ */
33
+ export function generatePermissionString(serverName, toolName) {
34
+ return `mcp__${serverName}__${toolName}`;
35
+ }
36
+ /**
37
+ * Parse a permission string into its components
38
+ */
39
+ export function parsePermissionString(permission) {
40
+ const match = permission.match(/^mcp__([^_]+)__(.+)$/);
41
+ if (!match || !match[1] || !match[2])
42
+ return null;
43
+ return { server: match[1], tool: match[2] };
44
+ }
45
+ /**
46
+ * Load Claude settings from a file
47
+ */
48
+ export function loadClaudeSettings(path) {
49
+ if (!existsSync(path)) {
50
+ return null;
51
+ }
52
+ try {
53
+ const content = readFileSync(path, 'utf-8');
54
+ return safeJsonParse(content, {});
55
+ }
56
+ catch (error) {
57
+ logger.error(`Failed to load settings from ${path}`, { error: String(error) });
58
+ return null;
59
+ }
60
+ }
61
+ /**
62
+ * Save Claude settings to a file
63
+ */
64
+ export function saveClaudeSettings(path, settings) {
65
+ try {
66
+ // Ensure directory exists
67
+ const dir = join(path, '..');
68
+ if (!existsSync(dir)) {
69
+ const { mkdirSync } = require('node:fs');
70
+ mkdirSync(dir, { recursive: true });
71
+ }
72
+ writeFileSync(path, JSON.stringify(settings, null, 2) + '\n');
73
+ return true;
74
+ }
75
+ catch (error) {
76
+ logger.error(`Failed to save settings to ${path}`, { error: String(error) });
77
+ return false;
78
+ }
79
+ }
80
+ /**
81
+ * Get existing MCP permissions from settings
82
+ */
83
+ export function getExistingPermissions(settings) {
84
+ const existing = new Set();
85
+ const allowList = settings.permissions?.allow || [];
86
+ for (const perm of allowList) {
87
+ if (perm.startsWith('mcp__')) {
88
+ existing.add(perm);
89
+ }
90
+ }
91
+ return existing;
92
+ }
93
+ /**
94
+ * Generate permission entries from server/tool list
95
+ */
96
+ export function generatePermissionEntries(tools) {
97
+ return tools.map(({ server, tool }) => ({
98
+ permission: generatePermissionString(server, tool),
99
+ server,
100
+ tool,
101
+ }));
102
+ }
103
+ /**
104
+ * Compare generated permissions against existing ones
105
+ */
106
+ export function comparePermissions(generated, existing) {
107
+ const newPerms = [];
108
+ const existingPerms = [];
109
+ for (const entry of generated) {
110
+ if (existing.has(entry.permission)) {
111
+ existingPerms.push(entry);
112
+ }
113
+ else {
114
+ newPerms.push(entry);
115
+ }
116
+ }
117
+ return {
118
+ all: generated,
119
+ new: newPerms,
120
+ existing: existingPerms,
121
+ };
122
+ }
123
+ /**
124
+ * Add permissions to settings
125
+ */
126
+ export function addPermissionsToSettings(settings, permissions) {
127
+ const updated = { ...settings };
128
+ if (!updated.permissions) {
129
+ updated.permissions = {};
130
+ }
131
+ if (!updated.permissions.allow) {
132
+ updated.permissions.allow = [];
133
+ }
134
+ const existing = new Set(updated.permissions.allow);
135
+ const toAdd = permissions.filter((p) => !existing.has(p));
136
+ updated.permissions.allow = [...updated.permissions.allow, ...toAdd];
137
+ return updated;
138
+ }
139
+ /**
140
+ * Format permissions for display
141
+ */
142
+ export function formatPermissionsForDisplay(entries) {
143
+ const byServer = new Map();
144
+ for (const entry of entries) {
145
+ const tools = byServer.get(entry.server) || [];
146
+ tools.push(entry.tool);
147
+ byServer.set(entry.server, tools);
148
+ }
149
+ const lines = [];
150
+ for (const [server, tools] of byServer) {
151
+ lines.push(`\n${server}:`);
152
+ for (const tool of tools.sort()) {
153
+ lines.push(` - ${tool}`);
154
+ }
155
+ }
156
+ return lines.join('\n');
157
+ }
158
+ /**
159
+ * Generate JSON array of permission strings for copying
160
+ */
161
+ export function formatPermissionsAsJson(entries) {
162
+ const permissions = entries.map((e) => e.permission).sort();
163
+ return JSON.stringify(permissions, null, 2);
164
+ }
165
+ //# sourceMappingURL=permissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/utils/permissions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Token bucket rate limiter for MCP servers
3
+ */
4
+ import { EventEmitter } from 'node:events';
5
+ import type { RateLimitConfig } from '../config/schema.js';
6
+ export interface RateLimiterStats {
7
+ serverName: string;
8
+ availableTokens: number;
9
+ maxTokens: number;
10
+ requestsPerSecond: number;
11
+ queueLength: number;
12
+ totalRequests: number;
13
+ totalWaited: number;
14
+ totalRejected: number;
15
+ }
16
+ export interface RateLimiterEvents {
17
+ waiting: {
18
+ serverName: string;
19
+ queuePosition: number;
20
+ estimatedWaitMs: number;
21
+ };
22
+ acquired: {
23
+ serverName: string;
24
+ waitedMs: number;
25
+ };
26
+ rejected: {
27
+ serverName: string;
28
+ reason: string;
29
+ };
30
+ }
31
+ /**
32
+ * Token bucket rate limiter with queue and reject modes
33
+ */
34
+ export declare class RateLimiter extends EventEmitter {
35
+ private readonly serverName;
36
+ private readonly requestsPerSecond;
37
+ private readonly maxTokens;
38
+ private readonly mode;
39
+ private readonly maxQueueTimeMs;
40
+ private tokens;
41
+ private lastRefill;
42
+ private queue;
43
+ private refillInterval;
44
+ private totalRequests;
45
+ private totalWaited;
46
+ private totalRejected;
47
+ constructor(config: RateLimitConfig, serverName: string);
48
+ /**
49
+ * Acquire a token before making a request
50
+ * In queue mode: waits until a token is available
51
+ * In reject mode: throws immediately if no token available
52
+ */
53
+ acquire(): Promise<void>;
54
+ /**
55
+ * Release a token back (for cancelled requests before they actually execute)
56
+ */
57
+ release(): void;
58
+ /**
59
+ * Get current rate limiter stats
60
+ */
61
+ getStats(): RateLimiterStats;
62
+ /**
63
+ * Clean up resources
64
+ */
65
+ destroy(): void;
66
+ /**
67
+ * Try to acquire a token without waiting
68
+ */
69
+ private tryAcquire;
70
+ /**
71
+ * Enqueue a request to wait for a token
72
+ */
73
+ private enqueue;
74
+ /**
75
+ * Refill tokens based on elapsed time
76
+ */
77
+ private refillTokens;
78
+ /**
79
+ * Start background timer to process queued requests
80
+ */
81
+ private startRefillTimer;
82
+ /**
83
+ * Process queued requests when tokens become available
84
+ */
85
+ private processQueue;
86
+ }
87
+ //# sourceMappingURL=rate-limiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../src/utils/rate-limiter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAG3D,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE,CAAC;IAChF,QAAQ,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACnD,QAAQ,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAClD;AASD;;GAEG;AACH,qBAAa,WAAY,SAAQ,YAAY;IAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAqB;IAC1C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IAExC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,cAAc,CAA+B;IAGrD,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,aAAa,CAAK;gBAEd,MAAM,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM;IAsBvD;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB9B;;OAEG;IACH,OAAO,IAAI,IAAI;IAIf;;OAEG;IACH,QAAQ,IAAI,gBAAgB;IAa5B;;OAEG;IACH,OAAO,IAAI,IAAI;IAgBf;;OAEG;IACH,OAAO,CAAC,UAAU;IAUlB;;OAEG;IACH,OAAO,CAAC,OAAO;IAwCf;;OAEG;IACH,OAAO,CAAC,YAAY;IAapB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAOxB;;OAEG;IACH,OAAO,CAAC,YAAY;CAkBrB"}