aegiscode 3.1.8 → 3.1.10

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 (206) hide show
  1. package/README.md +23 -15
  2. package/dist/main.js +549 -552
  3. package/package.json +4 -2
  4. package/src/agent/Agent.ts +903 -0
  5. package/src/agent/SimpleAgent.ts +48 -0
  6. package/src/agent/index.ts +54 -0
  7. package/src/agent/orchestrator/AppBuilder.ts +443 -0
  8. package/src/agent/orchestrator/CouncilAgent.ts +310 -0
  9. package/src/agent/orchestrator/DiscussionRoom.ts +462 -0
  10. package/src/agent/orchestrator/OrchestratorAgent.ts +637 -0
  11. package/src/agent/orchestrator/index.ts +38 -0
  12. package/src/agent/orchestrator/utils.ts +397 -0
  13. package/src/agent/pricing.ts +115 -0
  14. package/src/agent/router.ts +74 -0
  15. package/src/agent/routerStats.ts +121 -0
  16. package/src/agent/types.ts +318 -0
  17. package/src/auth/login.ts +383 -0
  18. package/src/cli/config.ts +189 -0
  19. package/src/cli/index.ts +17 -0
  20. package/src/cli/middleware.ts +119 -0
  21. package/src/cli/types.ts +75 -0
  22. package/src/config/ConfigManager.ts +587 -0
  23. package/src/config/index.ts +7 -0
  24. package/src/config/types.ts +584 -0
  25. package/src/context/CompactionService.ts +300 -0
  26. package/src/context/ContextManager.ts +450 -0
  27. package/src/context/FileAnalyzer.ts +267 -0
  28. package/src/context/TokenCounter.ts +265 -0
  29. package/src/context/index.ts +27 -0
  30. package/src/context/storage/CacheStore.ts +176 -0
  31. package/src/context/storage/JSONLStore.ts +201 -0
  32. package/src/context/storage/MemoryStore.ts +205 -0
  33. package/src/context/storage/PersistentStore.ts +327 -0
  34. package/src/context/storage/index.ts +9 -0
  35. package/src/context/storage/pathUtils.ts +114 -0
  36. package/src/context/test.ts +309 -0
  37. package/src/context/types.ts +268 -0
  38. package/src/hooks/HookExecutor.ts +434 -0
  39. package/src/hooks/HookManager.ts +596 -0
  40. package/src/hooks/HookService.ts +269 -0
  41. package/src/hooks/Matcher.ts +157 -0
  42. package/src/hooks/index.ts +63 -0
  43. package/src/hooks/types.ts +424 -0
  44. package/src/main.tsx +596 -0
  45. package/src/mcp/HealthMonitor.ts +150 -0
  46. package/src/mcp/McpClient.ts +491 -0
  47. package/src/mcp/McpRegistry.ts +321 -0
  48. package/src/mcp/createMcpTool.ts +251 -0
  49. package/src/mcp/index.ts +15 -0
  50. package/src/mcp/server.ts +334 -0
  51. package/src/mcp/test-server.ts +88 -0
  52. package/src/mcp/test.ts +372 -0
  53. package/src/mcp/types.ts +247 -0
  54. package/src/memory/AgentMemoryBus.ts +432 -0
  55. package/src/memory/CloudSync.ts +99 -0
  56. package/src/memory/DriveSync.ts +106 -0
  57. package/src/memory/SharedMemory.ts +951 -0
  58. package/src/memory/index.ts +14 -0
  59. package/src/memory/machineFingerprint.ts +40 -0
  60. package/src/orchestrator/SubAgentMetadata.ts +136 -0
  61. package/src/prompts/builder.ts +213 -0
  62. package/src/prompts/default.ts +144 -0
  63. package/src/prompts/index.ts +16 -0
  64. package/src/prompts/plan.ts +64 -0
  65. package/src/prompts/test.ts +78 -0
  66. package/src/services/AnthropicChatService.ts +341 -0
  67. package/src/services/ChatService.ts +347 -0
  68. package/src/services/ClaudeCliChatService.ts +256 -0
  69. package/src/services/CloudSync.ts +168 -0
  70. package/src/services/CostLedger.ts +211 -0
  71. package/src/services/Heartbeat.ts +135 -0
  72. package/src/services/LearningCollector.ts +291 -0
  73. package/src/services/OllamaInstaller.ts +342 -0
  74. package/src/services/VersionChecker.ts +445 -0
  75. package/src/services/index.ts +57 -0
  76. package/src/services/streaming/OpenAIEventAdapter.ts +126 -0
  77. package/src/services/streaming/RenderingProfile.ts +90 -0
  78. package/src/services/streaming/StreamEventParser.ts +181 -0
  79. package/src/services/streaming/ThrottledRenderer.ts +139 -0
  80. package/src/services/streaming/TranscriptBuffer.ts +574 -0
  81. package/src/services/streaming/eventStatusMap.ts +52 -0
  82. package/src/services/streaming/index.ts +46 -0
  83. package/src/services/streaming/renderFormatting.ts +79 -0
  84. package/src/services/streaming/types.ts +234 -0
  85. package/src/skills/SkillLoader.ts +126 -0
  86. package/src/skills/SkillRegistry.ts +366 -0
  87. package/src/skills/index.ts +48 -0
  88. package/src/skills/types.ts +146 -0
  89. package/src/slash-commands/billing.ts +70 -0
  90. package/src/slash-commands/build.ts +413 -0
  91. package/src/slash-commands/builtinCommands.ts +2733 -0
  92. package/src/slash-commands/clone.ts +242 -0
  93. package/src/slash-commands/council.ts +125 -0
  94. package/src/slash-commands/custom/CustomCommandExecutor.ts +143 -0
  95. package/src/slash-commands/custom/CustomCommandLoader.ts +251 -0
  96. package/src/slash-commands/custom/CustomCommandRegistry.ts +144 -0
  97. package/src/slash-commands/custom/index.ts +7 -0
  98. package/src/slash-commands/debate.ts +254 -0
  99. package/src/slash-commands/gmail.ts +105 -0
  100. package/src/slash-commands/index.ts +388 -0
  101. package/src/slash-commands/mcpCommand.ts +205 -0
  102. package/src/slash-commands/types.ts +201 -0
  103. package/src/store/index.ts +76 -0
  104. package/src/store/selectors.ts +246 -0
  105. package/src/store/slices/appSlice.ts +205 -0
  106. package/src/store/slices/commandSlice.ts +115 -0
  107. package/src/store/slices/configSlice.ts +46 -0
  108. package/src/store/slices/focusSlice.ts +64 -0
  109. package/src/store/slices/index.ts +9 -0
  110. package/src/store/slices/sessionSlice.ts +424 -0
  111. package/src/store/streaming-buffer.ts +425 -0
  112. package/src/store/test.ts +296 -0
  113. package/src/store/types.ts +274 -0
  114. package/src/store/vanilla.ts +186 -0
  115. package/src/tools/builtin/bash.ts +236 -0
  116. package/src/tools/builtin/council.ts +105 -0
  117. package/src/tools/builtin/edit.ts +213 -0
  118. package/src/tools/builtin/glob.ts +136 -0
  119. package/src/tools/builtin/grep.ts +263 -0
  120. package/src/tools/builtin/index.ts +61 -0
  121. package/src/tools/builtin/memory.ts +66 -0
  122. package/src/tools/builtin/read.ts +168 -0
  123. package/src/tools/builtin/skill.ts +97 -0
  124. package/src/tools/builtin/snapshot.ts +40 -0
  125. package/src/tools/builtin/task.ts +106 -0
  126. package/src/tools/builtin/write.ts +134 -0
  127. package/src/tools/createTool.ts +221 -0
  128. package/src/tools/execution/ExecutionPipeline.ts +263 -0
  129. package/src/tools/execution/index.ts +40 -0
  130. package/src/tools/execution/stages/CacheStage.ts +131 -0
  131. package/src/tools/execution/stages/ConfirmationStage.ts +203 -0
  132. package/src/tools/execution/stages/DiscoveryStage.ts +46 -0
  133. package/src/tools/execution/stages/ExecutionStage.ts +48 -0
  134. package/src/tools/execution/stages/FormattingStage.ts +44 -0
  135. package/src/tools/execution/stages/HookStage.ts +72 -0
  136. package/src/tools/execution/stages/PermissionStage.ts +287 -0
  137. package/src/tools/execution/stages/PostHookStage.ts +71 -0
  138. package/src/tools/execution/stages/index.ts +12 -0
  139. package/src/tools/execution/test.ts +266 -0
  140. package/src/tools/execution/types.ts +273 -0
  141. package/src/tools/index.ts +81 -0
  142. package/src/tools/registry.ts +304 -0
  143. package/src/tools/schemas.ts +109 -0
  144. package/src/tools/test.ts +220 -0
  145. package/src/tools/types.ts +175 -0
  146. package/src/tools/validation/PermissionChecker.ts +242 -0
  147. package/src/tools/validation/SensitiveFileDetector.ts +210 -0
  148. package/src/tools/validation/index.ts +11 -0
  149. package/src/ui/App.tsx +166 -0
  150. package/src/ui/components/AegisInterface.tsx +484 -0
  151. package/src/ui/components/common/ChatSearch.tsx +150 -0
  152. package/src/ui/components/common/ErrorBoundary.tsx +82 -0
  153. package/src/ui/components/common/ExitMessage.tsx +120 -0
  154. package/src/ui/components/common/LoadingIndicator.tsx +49 -0
  155. package/src/ui/components/common/index.ts +6 -0
  156. package/src/ui/components/dialog/ConfirmationPrompt.tsx +208 -0
  157. package/src/ui/components/dialog/InteractiveSelector.tsx +149 -0
  158. package/src/ui/components/dialog/SetupWizard.tsx +297 -0
  159. package/src/ui/components/dialog/UpdatePrompt.tsx +155 -0
  160. package/src/ui/components/dialog/index.ts +8 -0
  161. package/src/ui/components/index.ts +28 -0
  162. package/src/ui/components/input/CommandSuggestions.tsx +139 -0
  163. package/src/ui/components/input/CustomTextInput.tsx +220 -0
  164. package/src/ui/components/input/InputArea.tsx +361 -0
  165. package/src/ui/components/input/PromptSuggestions.tsx +66 -0
  166. package/src/ui/components/input/index.ts +6 -0
  167. package/src/ui/components/layout/ChatStatusBar.tsx +90 -0
  168. package/src/ui/components/layout/ContextBar.tsx +79 -0
  169. package/src/ui/components/layout/MessageArea.tsx +96 -0
  170. package/src/ui/components/layout/MessageList.tsx +647 -0
  171. package/src/ui/components/layout/MessageSeparator.tsx +26 -0
  172. package/src/ui/components/layout/WelcomeMessage.tsx +93 -0
  173. package/src/ui/components/layout/index.ts +7 -0
  174. package/src/ui/components/markdown/CodeHighlighter.tsx +292 -0
  175. package/src/ui/components/markdown/MessageRenderer.tsx +1211 -0
  176. package/src/ui/components/markdown/index.ts +8 -0
  177. package/src/ui/components/markdown/parser.ts +336 -0
  178. package/src/ui/components/markdown/types.ts +66 -0
  179. package/src/ui/focus/FocusManager.ts +137 -0
  180. package/src/ui/focus/index.ts +13 -0
  181. package/src/ui/focus/types.ts +54 -0
  182. package/src/ui/focus/useFocus.ts +75 -0
  183. package/src/ui/hooks/index.ts +11 -0
  184. package/src/ui/hooks/useAgent.ts +284 -0
  185. package/src/ui/hooks/useCommandHistory.ts +87 -0
  186. package/src/ui/hooks/useCommandProcessor.ts +443 -0
  187. package/src/ui/hooks/useConfirmation.ts +99 -0
  188. package/src/ui/hooks/useCtrlCHandler.ts +100 -0
  189. package/src/ui/hooks/useInputBuffer.ts +122 -0
  190. package/src/ui/hooks/useTerminalSize.ts +68 -0
  191. package/src/ui/hooks/useTerminalWidth.ts +5 -0
  192. package/src/ui/hooks/useWindowedList.ts +118 -0
  193. package/src/ui/render-debugger.ts +621 -0
  194. package/src/ui/test.ts +189 -0
  195. package/src/ui/themes/ThemeManager.ts +332 -0
  196. package/src/ui/themes/aegisTheme.ts +87 -0
  197. package/src/ui/themes/darkTheme.ts +87 -0
  198. package/src/ui/themes/defaultTheme.ts +85 -0
  199. package/src/ui/themes/index.ts +10 -0
  200. package/src/ui/themes/lightTheme.ts +89 -0
  201. package/src/ui/themes/popularThemes.ts +187 -0
  202. package/src/ui/themes/types.ts +130 -0
  203. package/src/utils/clipboard.ts +48 -0
  204. package/src/utils/debug.ts +43 -0
  205. package/src/utils/environment.ts +68 -0
  206. package/src/utils/index.ts +10 -0
@@ -0,0 +1,334 @@
1
+ /**
2
+ * AEGIS MCP Server — Exposes native tools (read, write, edit, glob, grep, bash,
3
+ * memory_graph) via standard Model Context Protocol transport.
4
+ *
5
+ * Grok connects to this server as an MCP client and uses the tools as a
6
+ * sub-agent for planning, debugging, and refactoring tasks.
7
+ *
8
+ * Usage:
9
+ * npx tsx src/mcp/server.ts # stdio transport (default)
10
+ * npx tsx src/mcp/server.ts --port 3100 # SSE transport over HTTP
11
+ */
12
+
13
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
14
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
15
+ import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js';
16
+ import {
17
+ CallToolRequestSchema,
18
+ ListToolsRequestSchema,
19
+ } from '@modelcontextprotocol/sdk/types.js';
20
+ import { execSync, spawn } from 'child_process';
21
+ import * as fs from 'fs';
22
+ import * as path from 'path';
23
+ import * as http from 'http';
24
+ import * as readline from 'readline';
25
+
26
+ // ── Optimized Tool Schemas ────────────────────────────────────────────────
27
+ // Compact definitions for token efficiency — 78% fewer tokens vs verbose schemas.
28
+
29
+ const TOOLS = [
30
+ {
31
+ name: 'read',
32
+ description: 'Read file contents. Returns full text.',
33
+ inputSchema: {
34
+ type: 'object',
35
+ properties: {
36
+ file_path: { type: 'string', description: 'Absolute path to file' },
37
+ offset: { type: 'number', description: 'Optional line offset (0-based)' },
38
+ limit: { type: 'number', description: 'Optional max lines' },
39
+ },
40
+ required: ['file_path'],
41
+ },
42
+ },
43
+ {
44
+ name: 'write',
45
+ description: 'Write file contents. Creates parent dirs automatically.',
46
+ inputSchema: {
47
+ type: 'object',
48
+ properties: {
49
+ file_path: { type: 'string', description: 'Absolute path' },
50
+ contents: { type: 'string', description: 'Full file content' },
51
+ },
52
+ required: ['file_path', 'contents'],
53
+ },
54
+ },
55
+ {
56
+ name: 'edit',
57
+ description: 'Edit file via exact string replacement.',
58
+ inputSchema: {
59
+ type: 'object',
60
+ properties: {
61
+ file_path: { type: 'string', description: 'Absolute path to file' },
62
+ old_string: { type: 'string', description: 'Text to replace (must be unique)' },
63
+ new_string: { type: 'string', description: 'Replacement text' },
64
+ replace_all: { type: 'boolean', description: 'Replace all occurrences' },
65
+ },
66
+ required: ['file_path', 'old_string', 'new_string'],
67
+ },
68
+ },
69
+ {
70
+ name: 'glob',
71
+ description: 'Find files matching a glob pattern. Recursive by default.',
72
+ inputSchema: {
73
+ type: 'object',
74
+ properties: {
75
+ pattern: { type: 'string', description: 'Glob pattern, e.g. "*.ts"' },
76
+ path: { type: 'string', description: 'Optional search root' },
77
+ },
78
+ required: ['pattern'],
79
+ },
80
+ },
81
+ {
82
+ name: 'grep',
83
+ description: 'Search file contents with regex. Returns matches with line numbers.',
84
+ inputSchema: {
85
+ type: 'object',
86
+ properties: {
87
+ pattern: { type: 'string', description: 'Regex pattern' },
88
+ path: { type: 'string', description: 'Optional search root' },
89
+ include: { type: 'string', description: 'Glob filter, e.g. "*.py"' },
90
+ case_sensitive: { type: 'boolean', description: 'Default true' },
91
+ },
92
+ required: ['pattern'],
93
+ },
94
+ },
95
+ {
96
+ name: 'bash',
97
+ description: 'Execute a shell command. For security, runs with limited env.',
98
+ inputSchema: {
99
+ type: 'object',
100
+ properties: {
101
+ command: { type: 'string', description: 'Shell command to run' },
102
+ timeout: { type: 'number', description: 'Timeout in ms, default 30000' },
103
+ description: { type: 'string', description: 'Brief description for logging' },
104
+ },
105
+ required: ['command'],
106
+ },
107
+ },
108
+ {
109
+ name: 'memory_graph',
110
+ description: 'Query AEGIS semantic memory. Returns relevant facts and state.',
111
+ inputSchema: {
112
+ type: 'object',
113
+ properties: {
114
+ query: { type: 'string', description: 'Free-text search query' },
115
+ scope: {
116
+ type: 'string',
117
+ enum: ['project', 'user', 'global'],
118
+ description: 'Search scope',
119
+ },
120
+ limit: { type: 'number', description: 'Max results, default 10' },
121
+ },
122
+ required: ['query'],
123
+ },
124
+ },
125
+ ];
126
+
127
+ // ── Tool Handlers ─────────────────────────────────────────────────────────
128
+
129
+ function handleRead(filePath: string, offset?: number, limit?: number): string {
130
+ if (!fs.existsSync(filePath)) return JSON.stringify({ error: `File not found: ${filePath}` });
131
+ const content = fs.readFileSync(filePath, 'utf-8');
132
+ const lines = content.split('\n');
133
+ const start = offset ?? 0;
134
+ const end = limit ? start + limit : lines.length;
135
+ return lines.slice(start, end).join('\n');
136
+ }
137
+
138
+ function handleWrite(filePath: string, contents: string): string {
139
+ fs.mkdirSync(path.dirname(path.resolve(filePath)), { recursive: true });
140
+ fs.writeFileSync(filePath, contents, 'utf-8');
141
+ return JSON.stringify({ success: true, bytes: Buffer.byteLength(contents, 'utf-8') });
142
+ }
143
+
144
+ function handleEdit(filePath: string, oldStr: string, newStr: string, replaceAll?: boolean): string {
145
+ if (!fs.existsSync(filePath)) return JSON.stringify({ error: `File not found: ${filePath}` });
146
+ let content = fs.readFileSync(filePath, 'utf-8');
147
+ if (replaceAll) {
148
+ content = content.split(oldStr).join(newStr);
149
+ } else {
150
+ const idx = content.indexOf(oldStr);
151
+ if (idx === -1) return JSON.stringify({ error: 'old_string not found' });
152
+ content = content.slice(0, idx) + newStr + content.slice(idx + oldStr.length);
153
+ }
154
+ fs.writeFileSync(filePath, content, 'utf-8');
155
+ return JSON.stringify({ success: true });
156
+ }
157
+
158
+ function handleGlob(pattern: string, searchPath?: string): string {
159
+ const { globSync } = require('glob');
160
+ const root = searchPath || process.cwd();
161
+ const matches = globSync(pattern, { cwd: root, nodir: false });
162
+ return JSON.stringify({ matches: matches.slice(0, 200), total: matches.length });
163
+ }
164
+
165
+ function handleGrep(pattern: string, searchPath?: string, include?: string, caseSensitive?: boolean): string {
166
+ try {
167
+ const root = searchPath || '.';
168
+ const ignoreCase = caseSensitive === false ? '-i' : '';
169
+ const extFilter = include ? `--include="${include}"` : '';
170
+ const result = execSync(`grep -rn ${ignoreCase} ${extFilter} "${pattern}" ${root}`, {
171
+ encoding: 'utf-8',
172
+ timeout: 15000,
173
+ maxBuffer: 1024 * 1024,
174
+ });
175
+ const lines = result.trim().split('\n').filter(Boolean);
176
+ return JSON.stringify({ matches: lines.slice(0, 100), total: lines.length });
177
+ } catch {
178
+ return JSON.stringify({ matches: [], total: 0 });
179
+ }
180
+ }
181
+
182
+ function handleBash(command: string, timeout?: number, description?: string): string {
183
+ try {
184
+ const t = Math.min((timeout || 30000), 60000);
185
+ const result = execSync(command, {
186
+ encoding: 'utf-8',
187
+ timeout: t,
188
+ maxBuffer: 10 * 1024 * 1024,
189
+ env: { ...process.env, PATH: process.env.PATH || '/usr/local/bin:/usr/bin:/bin' },
190
+ });
191
+ return JSON.stringify({
192
+ stdout: result.slice(0, 50000),
193
+ stderr: '',
194
+ returncode: 0,
195
+ description: description || '',
196
+ });
197
+ } catch (e: any) {
198
+ return JSON.stringify({
199
+ stdout: e.stdout?.slice(0, 50000) || '',
200
+ stderr: e.stderr?.slice(0, 10000) || e.message?.slice(0, 200) || 'exec error',
201
+ returncode: e.status ?? -1,
202
+ });
203
+ }
204
+ }
205
+
206
+ function handleMemoryGraph(query: string, scope?: string, limit?: number): string {
207
+ // Memory graph queries go through the AEGIS embedding service via HTTP.
208
+ // If the AEGIS API is available locally, query it. Otherwise return empty.
209
+ try {
210
+ const apiUrl = process.env.AEGIS_API_URL || 'http://localhost:5000';
211
+ const body = JSON.stringify({ query, limit: limit || 10, scope: scope || 'project' });
212
+ const result = execSync(
213
+ `curl -s -X POST "${apiUrl}/api/memory/search" -H "Content-Type: application/json" --data-binary @-`,
214
+ { encoding: 'utf-8', timeout: 10000, input: body }
215
+ );
216
+ return result;
217
+ } catch {
218
+ // Memory not available — return empty
219
+ return JSON.stringify({ results: [], query, total: 0 });
220
+ }
221
+ }
222
+
223
+ // ── Create MCP Server ─────────────────────────────────────────────────────
224
+
225
+ const server = new Server(
226
+ { name: 'aegis-native-tools', version: '1.0.0' },
227
+ { capabilities: { tools: {} } }
228
+ );
229
+
230
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
231
+ tools: TOOLS,
232
+ }));
233
+
234
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
235
+ const { name, arguments: args } = request.params;
236
+ let result: string;
237
+
238
+ try {
239
+ switch (name) {
240
+ case 'read':
241
+ result = handleRead(args.file_path, args.offset, args.limit);
242
+ break;
243
+ case 'write':
244
+ result = handleWrite(args.file_path, args.contents);
245
+ break;
246
+ case 'edit':
247
+ result = handleEdit(args.file_path, args.old_string, args.new_string, args.replace_all);
248
+ break;
249
+ case 'glob':
250
+ result = handleGlob(args.pattern, args.path);
251
+ break;
252
+ case 'grep':
253
+ result = handleGrep(args.pattern, args.path, args.include, args.case_sensitive);
254
+ break;
255
+ case 'bash':
256
+ result = handleBash(args.command, args.timeout, args.description);
257
+ break;
258
+ case 'memory_graph':
259
+ result = handleMemoryGraph(args.query, args.scope, args.limit);
260
+ break;
261
+ default:
262
+ throw new Error(`Unknown tool: ${name}`);
263
+ }
264
+ } catch (e: any) {
265
+ return {
266
+ content: [{ type: 'text', text: JSON.stringify({ error: e.message || String(e) }) }],
267
+ isError: true,
268
+ };
269
+ }
270
+
271
+ return {
272
+ content: [{ type: 'text', text: result }],
273
+ isError: false,
274
+ };
275
+ });
276
+
277
+ // ── Startup ────────────────────────────────────────────────────────────────
278
+
279
+ async function main() {
280
+ const args = process.argv.slice(2);
281
+ const portIndex = args.indexOf('--port');
282
+ const port = portIndex !== -1 ? parseInt(args[portIndex + 1], 10) : null;
283
+
284
+ if (port) {
285
+ // HTTP + SSE transport (for remote Grok connections)
286
+ const transports: SSEServerTransport[] = [];
287
+ const app = http.createServer(async (req, res) => {
288
+ const url = new URL(req.url || '/', `http://localhost:${port}`);
289
+
290
+ if (url.pathname === '/sse') {
291
+ const transport = new SSEServerTransport('/messages', res);
292
+ transports.push(transport);
293
+ await server.connect(transport);
294
+ return;
295
+ }
296
+
297
+ if (url.pathname === '/messages') {
298
+ const transport = transports.find(t => t.sessionId === url.searchParams.get('sessionId'));
299
+ if (transport) {
300
+ await transport.handlePostMessage(req, res);
301
+ return;
302
+ }
303
+ res.writeHead(404);
304
+ res.end('Not found');
305
+ return;
306
+ }
307
+
308
+ // Health check
309
+ if (url.pathname === '/health') {
310
+ res.writeHead(200, { 'Content-Type': 'application/json' });
311
+ res.end(JSON.stringify({ status: 'ok', tools: TOOLS.length }));
312
+ return;
313
+ }
314
+
315
+ res.writeHead(404);
316
+ res.end('Not found');
317
+ });
318
+
319
+ app.listen(port, () => {
320
+ process.stderr.write(`[AEGIS MCP Server] SSE transport on http://localhost:${port}/sse\n`);
321
+ process.stderr.write(`[AEGIS MCP Server] ${TOOLS.length} tools available\n`);
322
+ });
323
+ } else {
324
+ // stdio transport (default, for local Grok sub-process)
325
+ const transport = new StdioServerTransport();
326
+ await server.connect(transport);
327
+ process.stderr.write('[AEGIS MCP Server] stdio transport — running\n');
328
+ }
329
+ }
330
+
331
+ main().catch((e) => {
332
+ process.stderr.write(`[AEGIS MCP Server] Fatal: ${e}\n`);
333
+ process.exit(1);
334
+ });
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ *
4
+ *
5
+ *
6
+ *
7
+ *
8
+ * - echo: 返回输入的文本
9
+ * - time: 返回当前时间
10
+ */
11
+
12
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
13
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
14
+ import {
15
+ CallToolRequestSchema,
16
+ ListToolsRequestSchema,
17
+ } from '@modelcontextprotocol/sdk/types.js';
18
+
19
+ const server = new Server(
20
+ {
21
+ name: 'test-server',
22
+ version: '1.0.0',
23
+ },
24
+ {
25
+ capabilities: {
26
+ tools: {},
27
+ },
28
+ }
29
+ );
30
+
31
+ // 列出工
32
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
33
+ return {
34
+ tools: [
35
+ {
36
+ name: 'echo',
37
+ description: 'Echo back the input text',
38
+ inputSchema: {
39
+ type: 'object',
40
+ properties: {
41
+ text: {
42
+ type: 'string',
43
+ description: 'Text to echo',
44
+ },
45
+ },
46
+ required: ['text'],
47
+ },
48
+ },
49
+ {
50
+ name: 'time',
51
+ description: 'Get current time',
52
+ inputSchema: {
53
+ type: 'object',
54
+ properties: {},
55
+ },
56
+ },
57
+ ],
58
+ };
59
+ });
60
+
61
+ // 调用工
62
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
63
+ const { name, arguments: args } = request.params;
64
+
65
+ if (name === 'echo') {
66
+ const text = (args as { text?: string })?.text || '';
67
+ return {
68
+ content: [{ type: 'text', text: `Echo: ${text}` }],
69
+ };
70
+ }
71
+
72
+ if (name === 'time') {
73
+ return {
74
+ content: [{ type: 'text', text: `Current time: ${new Date().toISOString()}` }],
75
+ };
76
+ }
77
+
78
+ throw new Error(`Unknown tool: ${name}`);
79
+ });
80
+
81
+ // 启动服务
82
+ async function main() {
83
+ const transport = new StdioServerTransport();
84
+ await server.connect(transport);
85
+ console.error('Test MCP server running on stdio');
86
+ }
87
+
88
+ main().catch(console.error);