modular-studio 0.2.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 (187) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +261 -0
  3. package/dist/assets/graphPopulator-C6jg83nL.js +1 -0
  4. package/dist/assets/index-CXhIX28x.js +634 -0
  5. package/dist/assets/index-CeNF0r-K.css +1 -0
  6. package/dist/assets/jszip.min-BlpRodxc.js +2 -0
  7. package/dist/index.html +16 -0
  8. package/dist/vite.svg +1 -0
  9. package/dist-server/bin/modular-mcp.d.ts +8 -0
  10. package/dist-server/bin/modular-mcp.d.ts.map +1 -0
  11. package/dist-server/bin/modular-mcp.js +158 -0
  12. package/dist-server/bin/modular-mcp.js.map +1 -0
  13. package/dist-server/bin/modular-studio.d.ts +3 -0
  14. package/dist-server/bin/modular-studio.d.ts.map +1 -0
  15. package/dist-server/bin/modular-studio.js +63 -0
  16. package/dist-server/bin/modular-studio.js.map +1 -0
  17. package/dist-server/server/config.d.ts +4 -0
  18. package/dist-server/server/config.d.ts.map +1 -0
  19. package/dist-server/server/config.js +33 -0
  20. package/dist-server/server/config.js.map +1 -0
  21. package/dist-server/server/data/mcp-clients.json +5 -0
  22. package/dist-server/server/index.d.ts +3 -0
  23. package/dist-server/server/index.d.ts.map +1 -0
  24. package/dist-server/server/index.js +174 -0
  25. package/dist-server/server/index.js.map +1 -0
  26. package/dist-server/server/mcp/manager.d.ts +47 -0
  27. package/dist-server/server/mcp/manager.d.ts.map +1 -0
  28. package/dist-server/server/mcp/manager.js +203 -0
  29. package/dist-server/server/mcp/manager.js.map +1 -0
  30. package/dist-server/server/mcp/modular-server.d.ts +55 -0
  31. package/dist-server/server/mcp/modular-server.d.ts.map +1 -0
  32. package/dist-server/server/mcp/modular-server.js +492 -0
  33. package/dist-server/server/mcp/modular-server.js.map +1 -0
  34. package/dist-server/server/mcp/transport.d.ts +29 -0
  35. package/dist-server/server/mcp/transport.d.ts.map +1 -0
  36. package/dist-server/server/mcp/transport.js +61 -0
  37. package/dist-server/server/mcp/transport.js.map +1 -0
  38. package/dist-server/server/routes/agent-sdk.d.ts +3 -0
  39. package/dist-server/server/routes/agent-sdk.d.ts.map +1 -0
  40. package/dist-server/server/routes/agent-sdk.js +99 -0
  41. package/dist-server/server/routes/agent-sdk.js.map +1 -0
  42. package/dist-server/server/routes/agents.d.ts +10 -0
  43. package/dist-server/server/routes/agents.d.ts.map +1 -0
  44. package/dist-server/server/routes/agents.js +61 -0
  45. package/dist-server/server/routes/agents.js.map +1 -0
  46. package/dist-server/server/routes/auth-codex.d.ts +3 -0
  47. package/dist-server/server/routes/auth-codex.d.ts.map +1 -0
  48. package/dist-server/server/routes/auth-codex.js +51 -0
  49. package/dist-server/server/routes/auth-codex.js.map +1 -0
  50. package/dist-server/server/routes/capabilities.d.ts +3 -0
  51. package/dist-server/server/routes/capabilities.d.ts.map +1 -0
  52. package/dist-server/server/routes/capabilities.js +32 -0
  53. package/dist-server/server/routes/capabilities.js.map +1 -0
  54. package/dist-server/server/routes/claude-config.d.ts +3 -0
  55. package/dist-server/server/routes/claude-config.d.ts.map +1 -0
  56. package/dist-server/server/routes/claude-config.js +146 -0
  57. package/dist-server/server/routes/claude-config.js.map +1 -0
  58. package/dist-server/server/routes/connectors.d.ts +12 -0
  59. package/dist-server/server/routes/connectors.d.ts.map +1 -0
  60. package/dist-server/server/routes/connectors.js +325 -0
  61. package/dist-server/server/routes/connectors.js.map +1 -0
  62. package/dist-server/server/routes/embeddings.d.ts +6 -0
  63. package/dist-server/server/routes/embeddings.d.ts.map +1 -0
  64. package/dist-server/server/routes/embeddings.js +130 -0
  65. package/dist-server/server/routes/embeddings.js.map +1 -0
  66. package/dist-server/server/routes/health.d.ts +9 -0
  67. package/dist-server/server/routes/health.d.ts.map +1 -0
  68. package/dist-server/server/routes/health.js +284 -0
  69. package/dist-server/server/routes/health.js.map +1 -0
  70. package/dist-server/server/routes/knowledge.d.ts +3 -0
  71. package/dist-server/server/routes/knowledge.d.ts.map +1 -0
  72. package/dist-server/server/routes/knowledge.js +534 -0
  73. package/dist-server/server/routes/knowledge.js.map +1 -0
  74. package/dist-server/server/routes/llm.d.ts +3 -0
  75. package/dist-server/server/routes/llm.d.ts.map +1 -0
  76. package/dist-server/server/routes/llm.js +200 -0
  77. package/dist-server/server/routes/llm.js.map +1 -0
  78. package/dist-server/server/routes/mcp-oauth.d.ts +12 -0
  79. package/dist-server/server/routes/mcp-oauth.d.ts.map +1 -0
  80. package/dist-server/server/routes/mcp-oauth.js +137 -0
  81. package/dist-server/server/routes/mcp-oauth.js.map +1 -0
  82. package/dist-server/server/routes/mcp.d.ts +3 -0
  83. package/dist-server/server/routes/mcp.d.ts.map +1 -0
  84. package/dist-server/server/routes/mcp.js +177 -0
  85. package/dist-server/server/routes/mcp.js.map +1 -0
  86. package/dist-server/server/routes/pipeline.d.ts +45 -0
  87. package/dist-server/server/routes/pipeline.d.ts.map +1 -0
  88. package/dist-server/server/routes/pipeline.js +483 -0
  89. package/dist-server/server/routes/pipeline.js.map +1 -0
  90. package/dist-server/server/routes/providers.d.ts +3 -0
  91. package/dist-server/server/routes/providers.d.ts.map +1 -0
  92. package/dist-server/server/routes/providers.js +204 -0
  93. package/dist-server/server/routes/providers.js.map +1 -0
  94. package/dist-server/server/routes/qualification.d.ts +3 -0
  95. package/dist-server/server/routes/qualification.d.ts.map +1 -0
  96. package/dist-server/server/routes/qualification.js +105 -0
  97. package/dist-server/server/routes/qualification.js.map +1 -0
  98. package/dist-server/server/routes/repo-index.d.ts +4 -0
  99. package/dist-server/server/routes/repo-index.d.ts.map +1 -0
  100. package/dist-server/server/routes/repo-index.js +318 -0
  101. package/dist-server/server/routes/repo-index.js.map +1 -0
  102. package/dist-server/server/routes/runtime.d.ts +3 -0
  103. package/dist-server/server/routes/runtime.d.ts.map +1 -0
  104. package/dist-server/server/routes/runtime.js +122 -0
  105. package/dist-server/server/routes/runtime.js.map +1 -0
  106. package/dist-server/server/routes/skills-search.d.ts +3 -0
  107. package/dist-server/server/routes/skills-search.d.ts.map +1 -0
  108. package/dist-server/server/routes/skills-search.js +198 -0
  109. package/dist-server/server/routes/skills-search.js.map +1 -0
  110. package/dist-server/server/routes/worktrees.d.ts +3 -0
  111. package/dist-server/server/routes/worktrees.d.ts.map +1 -0
  112. package/dist-server/server/routes/worktrees.js +70 -0
  113. package/dist-server/server/routes/worktrees.js.map +1 -0
  114. package/dist-server/server/services/__tests__/embeddingService.test.d.ts +5 -0
  115. package/dist-server/server/services/__tests__/embeddingService.test.d.ts.map +1 -0
  116. package/dist-server/server/services/__tests__/embeddingService.test.js +233 -0
  117. package/dist-server/server/services/__tests__/embeddingService.test.js.map +1 -0
  118. package/dist-server/server/services/agentRunner.d.ts +46 -0
  119. package/dist-server/server/services/agentRunner.d.ts.map +1 -0
  120. package/dist-server/server/services/agentRunner.js +295 -0
  121. package/dist-server/server/services/agentRunner.js.map +1 -0
  122. package/dist-server/server/services/agentStore.d.ts +40 -0
  123. package/dist-server/server/services/agentStore.d.ts.map +1 -0
  124. package/dist-server/server/services/agentStore.js +62 -0
  125. package/dist-server/server/services/agentStore.js.map +1 -0
  126. package/dist-server/server/services/contentStore.d.ts +32 -0
  127. package/dist-server/server/services/contentStore.d.ts.map +1 -0
  128. package/dist-server/server/services/contentStore.js +68 -0
  129. package/dist-server/server/services/contentStore.js.map +1 -0
  130. package/dist-server/server/services/embeddingService.d.ts +53 -0
  131. package/dist-server/server/services/embeddingService.d.ts.map +1 -0
  132. package/dist-server/server/services/embeddingService.js +199 -0
  133. package/dist-server/server/services/embeddingService.js.map +1 -0
  134. package/dist-server/server/services/factExtractor.d.ts +14 -0
  135. package/dist-server/server/services/factExtractor.d.ts.map +1 -0
  136. package/dist-server/server/services/factExtractor.js +126 -0
  137. package/dist-server/server/services/factExtractor.js.map +1 -0
  138. package/dist-server/server/services/githubIndexer.d.ts +59 -0
  139. package/dist-server/server/services/githubIndexer.d.ts.map +1 -0
  140. package/dist-server/server/services/githubIndexer.js +183 -0
  141. package/dist-server/server/services/githubIndexer.js.map +1 -0
  142. package/dist-server/server/services/mcpOAuth.d.ts +32 -0
  143. package/dist-server/server/services/mcpOAuth.d.ts.map +1 -0
  144. package/dist-server/server/services/mcpOAuth.js +264 -0
  145. package/dist-server/server/services/mcpOAuth.js.map +1 -0
  146. package/dist-server/server/services/memoryScorer.d.ts +19 -0
  147. package/dist-server/server/services/memoryScorer.d.ts.map +1 -0
  148. package/dist-server/server/services/memoryScorer.js +147 -0
  149. package/dist-server/server/services/memoryScorer.js.map +1 -0
  150. package/dist-server/server/services/repoIndexer.d.ts +91 -0
  151. package/dist-server/server/services/repoIndexer.d.ts.map +1 -0
  152. package/dist-server/server/services/repoIndexer.js +512 -0
  153. package/dist-server/server/services/repoIndexer.js.map +1 -0
  154. package/dist-server/server/services/teamRunner.d.ts +39 -0
  155. package/dist-server/server/services/teamRunner.d.ts.map +1 -0
  156. package/dist-server/server/services/teamRunner.js +76 -0
  157. package/dist-server/server/services/teamRunner.js.map +1 -0
  158. package/dist-server/server/services/worktreeManager.d.ts +27 -0
  159. package/dist-server/server/services/worktreeManager.d.ts.map +1 -0
  160. package/dist-server/server/services/worktreeManager.js +107 -0
  161. package/dist-server/server/services/worktreeManager.js.map +1 -0
  162. package/dist-server/server/types.d.ts +30 -0
  163. package/dist-server/server/types.d.ts.map +1 -0
  164. package/dist-server/server/types.js +2 -0
  165. package/dist-server/server/types.js.map +1 -0
  166. package/dist-server/server/utils/pathSecurity.d.ts +34 -0
  167. package/dist-server/server/utils/pathSecurity.d.ts.map +1 -0
  168. package/dist-server/server/utils/pathSecurity.js +78 -0
  169. package/dist-server/server/utils/pathSecurity.js.map +1 -0
  170. package/dist-server/src/services/budgetAllocator.d.ts +37 -0
  171. package/dist-server/src/services/budgetAllocator.d.ts.map +1 -0
  172. package/dist-server/src/services/budgetAllocator.js +120 -0
  173. package/dist-server/src/services/budgetAllocator.js.map +1 -0
  174. package/dist-server/src/services/contradictionDetector.d.ts +18 -0
  175. package/dist-server/src/services/contradictionDetector.d.ts.map +1 -0
  176. package/dist-server/src/services/contradictionDetector.js +111 -0
  177. package/dist-server/src/services/contradictionDetector.js.map +1 -0
  178. package/dist-server/src/services/treeIndexer.d.ts +91 -0
  179. package/dist-server/src/services/treeIndexer.d.ts.map +1 -0
  180. package/dist-server/src/services/treeIndexer.js +289 -0
  181. package/dist-server/src/services/treeIndexer.js.map +1 -0
  182. package/dist-server/src/store/knowledgeBase.d.ts +130 -0
  183. package/dist-server/src/store/knowledgeBase.d.ts.map +1 -0
  184. package/dist-server/src/store/knowledgeBase.js +299 -0
  185. package/dist-server/src/store/knowledgeBase.js.map +1 -0
  186. package/dist-server/tsconfig.server.tsbuildinfo +1 -0
  187. package/package.json +92 -0
@@ -0,0 +1,4 @@
1
+ import type { AppConfig } from './types.js';
2
+ export declare function readConfig(): AppConfig;
3
+ export declare function writeConfig(config: AppConfig): void;
4
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../server/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAgB5C,wBAAgB,UAAU,IAAI,SAAS,CAYtC;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAGnD"}
@@ -0,0 +1,33 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ const CONFIG_DIR = join(homedir(), '.modular-studio');
5
+ const CONFIG_PATH = join(CONFIG_DIR, 'config.json');
6
+ const DEFAULT_CONFIG = {
7
+ providers: [],
8
+ mcpServers: [],
9
+ };
10
+ function ensureDir() {
11
+ if (!existsSync(CONFIG_DIR)) {
12
+ mkdirSync(CONFIG_DIR, { recursive: true });
13
+ }
14
+ }
15
+ export function readConfig() {
16
+ ensureDir();
17
+ if (!existsSync(CONFIG_PATH)) {
18
+ writeConfig(DEFAULT_CONFIG);
19
+ return { ...DEFAULT_CONFIG };
20
+ }
21
+ try {
22
+ const raw = readFileSync(CONFIG_PATH, 'utf-8');
23
+ return JSON.parse(raw);
24
+ }
25
+ catch {
26
+ return { ...DEFAULT_CONFIG };
27
+ }
28
+ }
29
+ export function writeConfig(config) {
30
+ ensureDir();
31
+ writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), 'utf-8');
32
+ }
33
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../server/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAGlC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,iBAAiB,CAAC,CAAC;AACtD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEpD,MAAM,cAAc,GAAc;IAChC,SAAS,EAAE,EAAE;IACb,UAAU,EAAE,EAAE;CACf,CAAC;AAEF,SAAS,SAAS;IAChB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,SAAS,EAAE,CAAC;IACZ,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,WAAW,CAAC,cAAc,CAAC,CAAC;QAC5B,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC/B,CAAC;IACD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAiB;IAC3C,SAAS,EAAE,CAAC;IACZ,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACvE,CAAC"}
@@ -0,0 +1,5 @@
1
+ {
2
+ "https://mcp.notion.com/mcp": {
3
+ "client_id": "vrpnT7WPSCDwtLgd"
4
+ }
5
+ }
@@ -0,0 +1,3 @@
1
+ export declare function createApp(): import("express-serve-static-core").Express;
2
+ export declare function startServer(port?: number): import("http").Server<typeof import("http").IncomingMessage, typeof import("http").ServerResponse>;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../server/index.ts"],"names":[],"mappings":"AA6BA,wBAAgB,SAAS,gDAqFxB;AA+BD,wBAAgB,WAAW,CAAC,IAAI,GAAE,MAAa,sGAoB9C"}
@@ -0,0 +1,174 @@
1
+ import express from 'express';
2
+ import cors from 'cors';
3
+ import { join, dirname } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { existsSync } from 'node:fs';
6
+ import { readConfig } from './config.js';
7
+ import { mcpManager } from './mcp/manager.js';
8
+ import providerRoutes from './routes/providers.js';
9
+ import mcpRoutes from './routes/mcp.js';
10
+ import llmRoutes from './routes/llm.js';
11
+ import agentSdkRoutes from './routes/agent-sdk.js';
12
+ import knowledgeRoutes from './routes/knowledge.js';
13
+ import claudeConfigRoutes from './routes/claude-config.js';
14
+ import skillsSearchRoutes from './routes/skills-search.js';
15
+ import repoIndexRoutes, { cleanupLegacyGitHubKnowledgeDirs } from './routes/repo-index.js';
16
+ import healthRoutes from './routes/health.js';
17
+ import connectorRoutes from './routes/connectors.js';
18
+ import runtimeRoutes from './routes/runtime.js';
19
+ import worktreeRoutes from './routes/worktrees.js';
20
+ import authCodexRoutes from './routes/auth-codex.js';
21
+ import capabilitiesRoutes from './routes/capabilities.js';
22
+ import qualificationRoutes from './routes/qualification.js';
23
+ import agentRoutes from './routes/agents.js';
24
+ import mcpOAuthRoutes from './routes/mcp-oauth.js';
25
+ import pipelineRoutes from './routes/pipeline.js';
26
+ import embeddingRoutes from './routes/embeddings.js';
27
+ const __dirname = dirname(fileURLToPath(import.meta.url));
28
+ export function createApp() {
29
+ const app = express();
30
+ // CORS for dev
31
+ app.use(cors({
32
+ origin: [
33
+ 'http://localhost:5173',
34
+ 'http://localhost:5174',
35
+ 'http://localhost:5175',
36
+ 'http://localhost:5176',
37
+ ],
38
+ }));
39
+ app.use(express.json({ limit: '10mb' }));
40
+ // Basic security headers (lightweight helmet-like)
41
+ app.use((_req, res, next) => {
42
+ res.setHeader('X-Content-Type-Options', 'nosniff');
43
+ res.setHeader('X-Frame-Options', 'DENY');
44
+ res.setHeader('Referrer-Policy', 'no-referrer');
45
+ res.setHeader('Permissions-Policy', 'geolocation=(), microphone=(), camera=()');
46
+ next();
47
+ });
48
+ // Simple in-memory rate limiter for API routes
49
+ const rateWindowMs = 60_000;
50
+ const maxRequestsPerWindow = 600;
51
+ const ipHits = new Map();
52
+ app.use('/api', (req, res, next) => {
53
+ const ip = req.ip || 'unknown';
54
+ const now = Date.now();
55
+ const current = ipHits.get(ip);
56
+ if (!current || now > current.resetAt) {
57
+ ipHits.set(ip, { count: 1, resetAt: now + rateWindowMs });
58
+ return next();
59
+ }
60
+ if (current.count >= maxRequestsPerWindow) {
61
+ return res.status(429).json({ status: 'error', error: 'Rate limit exceeded' });
62
+ }
63
+ current.count += 1;
64
+ ipHits.set(ip, current);
65
+ next();
66
+ });
67
+ // API routes
68
+ app.use('/api/providers', providerRoutes);
69
+ app.use('/api/mcp/oauth', mcpOAuthRoutes(4800));
70
+ app.use('/api/mcp', mcpRoutes);
71
+ app.use('/api/llm', llmRoutes);
72
+ app.use('/api/agent-sdk', agentSdkRoutes);
73
+ app.use('/api/knowledge', knowledgeRoutes);
74
+ app.use('/api/claude-config', claudeConfigRoutes);
75
+ app.use('/api/skills', skillsSearchRoutes);
76
+ app.use('/api/repo', repoIndexRoutes);
77
+ app.use('/api/health', healthRoutes);
78
+ app.use('/api/connectors', connectorRoutes);
79
+ app.use('/api/runtime', runtimeRoutes);
80
+ app.use('/api/worktrees', worktreeRoutes);
81
+ app.use('/api/auth/codex', authCodexRoutes);
82
+ app.use('/api/capabilities', capabilitiesRoutes);
83
+ app.use('/api/qualification', qualificationRoutes);
84
+ app.use('/api/agents', agentRoutes);
85
+ app.use('/api/pipeline', pipelineRoutes);
86
+ app.use('/api/embeddings', embeddingRoutes);
87
+ // Global error handler — prevent server crashes
88
+ app.use((err, _req, res, _next) => {
89
+ console.error('Unhandled error:', err.message);
90
+ if (!res.headersSent) {
91
+ res.status(500).json({ status: 'error', error: err.message });
92
+ }
93
+ });
94
+ // Serve built frontend — check both source layout (../dist) and npm package layout (../../dist)
95
+ const distPath = existsSync(join(__dirname, '..', 'dist'))
96
+ ? join(__dirname, '..', 'dist')
97
+ : join(__dirname, '..', '..', 'dist');
98
+ if (existsSync(distPath)) {
99
+ app.use(express.static(distPath));
100
+ app.get('/{*path}', (_req, res) => {
101
+ res.sendFile(join(distPath, 'index.html'));
102
+ });
103
+ }
104
+ return app;
105
+ }
106
+ // Load saved MCP servers into manager on startup
107
+ function loadSavedServers() {
108
+ const config = readConfig();
109
+ const registeredIds = [];
110
+ for (const server of config.mcpServers) {
111
+ mcpManager.addServer(server);
112
+ registeredIds.push(server.id);
113
+ }
114
+ return registeredIds;
115
+ }
116
+ async function autoConnectSavedServers(serverIds) {
117
+ for (const serverId of serverIds) {
118
+ const server = mcpManager.getServer(serverId);
119
+ if (!server)
120
+ continue;
121
+ if (server.config.autoConnect === false) {
122
+ console.log(`[MCP] Skipping auto-connect for "${serverId}" (autoConnect=false)`);
123
+ continue;
124
+ }
125
+ try {
126
+ const result = await mcpManager.connect(serverId);
127
+ console.log(`[MCP] Auto-connected "${serverId}" with ${result.tools.length} tool(s)`);
128
+ }
129
+ catch (err) {
130
+ const message = err instanceof Error ? err.message : String(err);
131
+ console.error(`[MCP] Auto-connect failed for "${serverId}": ${message}`);
132
+ }
133
+ }
134
+ }
135
+ export function startServer(port = 4800) {
136
+ const removedLegacyDirs = cleanupLegacyGitHubKnowledgeDirs();
137
+ if (removedLegacyDirs > 0) {
138
+ console.log(`Cleaned ${removedLegacyDirs} legacy GitHub index director${removedLegacyDirs === 1 ? 'y' : 'ies'}`);
139
+ }
140
+ const registeredServerIds = loadSavedServers();
141
+ void autoConnectSavedServers(registeredServerIds);
142
+ const app = createApp();
143
+ const server = app.listen(port, () => {
144
+ const addr = server.address();
145
+ console.log(`Modular Studio running at http://localhost:${port}`, addr);
146
+ });
147
+ server.on('error', (err) => {
148
+ console.error(`Failed to start server on port ${port}:`, err.message);
149
+ if (err.code === 'EADDRINUSE') {
150
+ console.error(`Port ${port} is already in use`);
151
+ }
152
+ process.exit(1);
153
+ });
154
+ return server;
155
+ }
156
+ // Prevent crashes from unhandled rejections
157
+ process.on('uncaughtException', (err) => {
158
+ console.error('Uncaught exception:', err.message);
159
+ });
160
+ process.on('unhandledRejection', (err) => {
161
+ console.error('Unhandled rejection:', err instanceof Error ? err.message : err);
162
+ });
163
+ // Start when run directly via `npm run server` or `tsx server/index.ts`
164
+ // Check URL (Unix) or backslash-encoded URL (Windows) or argv for direct invocation
165
+ const selfUrl = import.meta.url || '';
166
+ const isMainModule = selfUrl.includes('server/index') || selfUrl.includes('server%5Cindex') || selfUrl.includes('server\\index');
167
+ if (isMainModule) {
168
+ const server = startServer();
169
+ // Prevent Node from exiting — keep-alive interval + signal handlers
170
+ const keepAlive = setInterval(() => { }, 1 << 30); // ~12 days
171
+ process.on('SIGINT', () => { clearInterval(keepAlive); server.close(); process.exit(0); });
172
+ process.on('SIGTERM', () => { clearInterval(keepAlive); server.close(); process.exit(0); });
173
+ }
174
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../server/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
3
+ import type { McpServerConfig } from '../types.js';
4
+ interface McpConnection {
5
+ config: McpServerConfig;
6
+ client: Client | null;
7
+ transport: StdioClientTransport | null;
8
+ status: 'disconnected' | 'connecting' | 'connected' | 'error';
9
+ tools: Array<{
10
+ name: string;
11
+ description?: string;
12
+ inputSchema?: unknown;
13
+ }>;
14
+ connectedAt: number | null;
15
+ lastError: string | null;
16
+ }
17
+ export declare class McpManager {
18
+ private connections;
19
+ private readonly ALLOWED_MCP_COMMANDS;
20
+ private readonly DANGEROUS_ENV_VARS;
21
+ private validateMcpCommand;
22
+ private validateMcpEnvironment;
23
+ private normalizeConfig;
24
+ addServer(config: McpServerConfig): void;
25
+ removeServer(id: string): void;
26
+ getServer(id: string): McpConnection | undefined;
27
+ listServers(): Array<McpServerConfig & {
28
+ status: string;
29
+ tools: McpConnection['tools'];
30
+ lastError: string | null;
31
+ }>;
32
+ connect(id: string): Promise<{
33
+ status: string;
34
+ tools: McpConnection['tools'];
35
+ }>;
36
+ callTool(id: string, toolName: string, args: Record<string, unknown>): Promise<unknown>;
37
+ disconnect(id: string): Promise<void>;
38
+ getHealth(id: string): {
39
+ status: string;
40
+ tools: McpConnection['tools'];
41
+ uptime: number | null;
42
+ lastError: string | null;
43
+ };
44
+ }
45
+ export declare const mcpManager: McpManager;
46
+ export {};
47
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../server/mcp/manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAGnD,UAAU,aAAa;IACrB,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACvC,MAAM,EAAE,cAAc,GAAG,YAAY,GAAG,WAAW,GAAG,OAAO,CAAC;IAC9D,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAC5E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,WAAW,CAAoC;IAGvD,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAElC;IAGH,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAEhC;IAEH,OAAO,CAAC,kBAAkB;IA0B1B,OAAO,CAAC,sBAAsB;IAc9B,OAAO,CAAC,eAAe;IASvB,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI;IAkBxC,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAI9B,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAIhD,WAAW,IAAI,KAAK,CAAC,eAAe,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;QAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAS7G,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAA;KAAE,CAAC;IA8F/E,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAWvF,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3C,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE;CAW1H;AAED,eAAO,MAAM,UAAU,YAAmB,CAAC"}
@@ -0,0 +1,203 @@
1
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
3
+ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
4
+ import { getToken } from '../services/mcpOAuth.js';
5
+ export class McpManager {
6
+ connections = new Map();
7
+ // Allowlist of safe MCP executables - SECURITY FIX
8
+ ALLOWED_MCP_COMMANDS = new Set([
9
+ 'npx', 'node', 'python', 'python3', 'uvx', 'uv', 'deno', 'bun'
10
+ ]);
11
+ // Dangerous environment variables to block - SECURITY FIX
12
+ DANGEROUS_ENV_VARS = new Set([
13
+ 'LD_PRELOAD', 'DYLD_INSERT_LIBRARIES', 'NODE_OPTIONS'
14
+ ]);
15
+ validateMcpCommand(command, args = []) {
16
+ if (!command) {
17
+ throw new Error('MCP command cannot be empty');
18
+ }
19
+ // Extract base command (remove path prefixes)
20
+ const baseCommand = command.split(/[/\\]/).pop()?.split('.')[0] || '';
21
+ // Check if command is in allowlist or starts with allowed prefix
22
+ const isAllowed = this.ALLOWED_MCP_COMMANDS.has(baseCommand) ||
23
+ Array.from(this.ALLOWED_MCP_COMMANDS).some(allowed => command.startsWith(allowed));
24
+ if (!isAllowed) {
25
+ throw new Error(`Unsafe MCP command "${command}". Only allowed: ${Array.from(this.ALLOWED_MCP_COMMANDS).join(', ')}`);
26
+ }
27
+ // Basic args validation - prevent obvious injection attempts
28
+ for (const arg of args) {
29
+ if (arg.includes('&&') || arg.includes('||') || arg.includes(';') || arg.includes('|')) {
30
+ throw new Error(`Unsafe argument detected: "${arg}"`);
31
+ }
32
+ }
33
+ }
34
+ validateMcpEnvironment(env = {}) {
35
+ for (const [key, value] of Object.entries(env)) {
36
+ // Block dangerous environment variables
37
+ if (this.DANGEROUS_ENV_VARS.has(key)) {
38
+ throw new Error(`Dangerous environment variable not allowed: ${key}`);
39
+ }
40
+ // Block NODE_OPTIONS with --require
41
+ if (key === 'NODE_OPTIONS' && value.includes('--require')) {
42
+ throw new Error('NODE_OPTIONS with --require not allowed for security');
43
+ }
44
+ }
45
+ }
46
+ normalizeConfig(config) {
47
+ return {
48
+ ...config,
49
+ args: config.args ?? [],
50
+ env: config.env ?? {},
51
+ autoConnect: config.autoConnect ?? true,
52
+ };
53
+ }
54
+ addServer(config) {
55
+ const normalizedConfig = this.normalizeConfig(config);
56
+ if (this.connections.has(config.id)) {
57
+ const existing = this.connections.get(config.id);
58
+ existing.config = normalizedConfig;
59
+ return;
60
+ }
61
+ this.connections.set(config.id, {
62
+ config: normalizedConfig,
63
+ client: null,
64
+ transport: null,
65
+ status: 'disconnected',
66
+ tools: [],
67
+ connectedAt: null,
68
+ lastError: null,
69
+ });
70
+ }
71
+ removeServer(id) {
72
+ this.connections.delete(id);
73
+ }
74
+ getServer(id) {
75
+ return this.connections.get(id);
76
+ }
77
+ listServers() {
78
+ return Array.from(this.connections.values()).map((c) => ({
79
+ ...c.config,
80
+ status: c.status,
81
+ tools: c.tools,
82
+ lastError: c.lastError,
83
+ }));
84
+ }
85
+ async connect(id) {
86
+ const conn = this.connections.get(id);
87
+ if (!conn)
88
+ throw new Error(`MCP server "${id}" not found`);
89
+ const transportType = conn.config.type || 'stdio';
90
+ if (transportType !== 'stdio' && transportType !== 'streamable-http') {
91
+ conn.status = 'error';
92
+ conn.lastError = 'Transport type ' + transportType + ' not yet supported. Use stdio or streamable-http.';
93
+ throw new Error(conn.lastError);
94
+ }
95
+ // Disconnect existing if any
96
+ if (conn.client) {
97
+ try {
98
+ await conn.client.close();
99
+ }
100
+ catch { /* ignore */ }
101
+ }
102
+ conn.status = 'connecting';
103
+ conn.lastError = null;
104
+ try {
105
+ let client;
106
+ if (transportType === 'streamable-http') {
107
+ // Remote MCP server via Streamable HTTP
108
+ const serverUrl = conn.config.url;
109
+ if (!serverUrl)
110
+ throw new Error('No URL configured for streamable-http server');
111
+ const headers = {};
112
+ const token = await getToken(serverUrl);
113
+ if (token) {
114
+ headers['Authorization'] = 'Bearer ' + token;
115
+ }
116
+ const transport = new StreamableHTTPClientTransport(new URL(serverUrl), { requestInit: { headers } });
117
+ client = new Client({ name: 'modular-studio', version: '1.0.0' });
118
+ await client.connect(transport);
119
+ const { tools } = await client.listTools();
120
+ conn.client = client;
121
+ conn.transport = null; // no stdio transport to store
122
+ conn.status = 'connected';
123
+ conn.tools = tools.map(t => ({ name: t.name, description: t.description, inputSchema: t.inputSchema }));
124
+ conn.connectedAt = Date.now();
125
+ return { status: 'connected', tools: conn.tools };
126
+ }
127
+ // Validate MCP server command and environment - SECURITY FIX
128
+ this.validateMcpCommand(conn.config.command, conn.config.args);
129
+ this.validateMcpEnvironment(conn.config.env);
130
+ const transport = new StdioClientTransport({
131
+ command: conn.config.command,
132
+ args: conn.config.args,
133
+ env: { ...process.env, ...conn.config.env },
134
+ });
135
+ client = new Client({ name: 'modular-studio', version: '1.0.0' });
136
+ // Handle process exit
137
+ transport.onclose = () => {
138
+ if (conn.status === 'connected') {
139
+ conn.status = 'error';
140
+ conn.lastError = 'Process exited unexpectedly';
141
+ conn.client = null;
142
+ conn.transport = null;
143
+ }
144
+ };
145
+ await client.connect(transport);
146
+ const { tools } = await client.listTools();
147
+ conn.client = client;
148
+ conn.transport = transport;
149
+ conn.status = 'connected';
150
+ conn.tools = tools.map((t) => ({
151
+ name: t.name,
152
+ description: t.description,
153
+ inputSchema: t.inputSchema,
154
+ }));
155
+ conn.connectedAt = Date.now();
156
+ return { status: 'connected', tools: conn.tools };
157
+ }
158
+ catch (err) {
159
+ conn.status = 'error';
160
+ conn.lastError = err instanceof Error ? err.message : String(err);
161
+ throw err;
162
+ }
163
+ }
164
+ async callTool(id, toolName, args) {
165
+ const conn = this.connections.get(id);
166
+ if (!conn)
167
+ throw new Error(`MCP server "${id}" not found`);
168
+ if (!conn.client || conn.status !== 'connected') {
169
+ throw new Error(`MCP server "${id}" is not connected`);
170
+ }
171
+ const result = await conn.client.callTool({ name: toolName, arguments: args });
172
+ return result;
173
+ }
174
+ async disconnect(id) {
175
+ const conn = this.connections.get(id);
176
+ if (!conn)
177
+ throw new Error(`MCP server "${id}" not found`);
178
+ if (conn.client) {
179
+ try {
180
+ await conn.client.close();
181
+ }
182
+ catch { /* ignore */ }
183
+ }
184
+ conn.client = null;
185
+ conn.transport = null;
186
+ conn.status = 'disconnected';
187
+ conn.tools = [];
188
+ conn.connectedAt = null;
189
+ }
190
+ getHealth(id) {
191
+ const conn = this.connections.get(id);
192
+ if (!conn)
193
+ throw new Error(`MCP server "${id}" not found`);
194
+ return {
195
+ status: conn.status,
196
+ tools: conn.tools,
197
+ uptime: conn.connectedAt ? Date.now() - conn.connectedAt : null,
198
+ lastError: conn.lastError,
199
+ };
200
+ }
201
+ }
202
+ export const mcpManager = new McpManager();
203
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../server/mcp/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Modular MCP Server - Universal Context Provider
3
+ *
4
+ * Exposes Modular Studio's context engineering pipeline as MCP tools:
5
+ * - modular_context: Full context engineering pipeline
6
+ * - modular_tree: Document tree indexing
7
+ * - modular_classify: Knowledge type classification
8
+ * - modular_facts: Fact extraction from text
9
+ * - modular_consolidate: Memory consolidation
10
+ */
11
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
12
+ import { type KnowledgeType } from '../../src/store/knowledgeBase.js';
13
+ import { type BudgetAllocation } from '../../src/services/budgetAllocator.js';
14
+ import { type ExtractedFact } from '../services/factExtractor.js';
15
+ export interface ModularContextInput {
16
+ sources: Array<{
17
+ path: string;
18
+ name: string;
19
+ type?: KnowledgeType;
20
+ }>;
21
+ task: string;
22
+ tokenBudget?: number;
23
+ }
24
+ export interface ModularContextOutput {
25
+ context: string;
26
+ metadata: {
27
+ totalTokens: number;
28
+ sources: Array<{
29
+ name: string;
30
+ type: KnowledgeType;
31
+ tokens: number;
32
+ depth: number;
33
+ }>;
34
+ budgetAllocation: BudgetAllocation[];
35
+ contradictions: number;
36
+ };
37
+ }
38
+ export interface ConsolidationResult {
39
+ kept: ExtractedFact[];
40
+ pruned: ExtractedFact[];
41
+ merged: Array<{
42
+ primary: ExtractedFact;
43
+ merged: ExtractedFact[];
44
+ }>;
45
+ promoted: ExtractedFact[];
46
+ }
47
+ /**
48
+ * Core context engineering pipeline
49
+ */
50
+ export declare function processModularContext(input: ModularContextInput): Promise<ModularContextOutput>;
51
+ /**
52
+ * Create and configure the MCP server
53
+ */
54
+ export declare function createModularServer(): Server;
55
+ //# sourceMappingURL=modular-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modular-server.d.ts","sourceRoot":"","sources":["../../../server/mcp/modular-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAWnE,OAAO,EAAgD,KAAK,aAAa,EAAmB,MAAM,kCAAkC,CAAC;AACrI,OAAO,EAAsC,KAAK,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAElH,OAAO,EAAgB,KAAK,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAIhF,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,aAAa,CAAC;KACtB,CAAC,CAAC;IACH,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE;QACR,WAAW,EAAE,MAAM,CAAC;QACpB,OAAO,EAAE,KAAK,CAAC;YACb,IAAI,EAAE,MAAM,CAAC;YACb,IAAI,EAAE,aAAa,CAAC;YACpB,MAAM,EAAE,MAAM,CAAC;YACf,KAAK,EAAE,MAAM,CAAC;SACf,CAAC,CAAC;QACH,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;QACrC,cAAc,EAAE,MAAM,CAAC;KACxB,CAAC;CACH;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,MAAM,EAAE,KAAK,CAAC;QACZ,OAAO,EAAE,aAAa,CAAC;QACvB,MAAM,EAAE,aAAa,EAAE,CAAC;KACzB,CAAC,CAAC;IACH,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAuIrG;AAkDD;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CA0R5C"}