@deimoscloud/coreai 0.1.9 → 0.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 (196) hide show
  1. package/dist/cli/index.js +1 -1
  2. package/dist/cli/index.js.map +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/package.json +6 -1
  6. package/.prettierrc +0 -9
  7. package/AGENT_SPEC.md +0 -347
  8. package/ARCHITECTURE.md +0 -547
  9. package/DRAFT_PRD.md +0 -1440
  10. package/IMPLEMENTATION_PLAN.md +0 -256
  11. package/PRODUCT.md +0 -473
  12. package/WORKFLOWS.md +0 -295
  13. package/commands/core/check-inbox.md +0 -34
  14. package/commands/core/delegate.md +0 -30
  15. package/commands/core/git-commit.md +0 -144
  16. package/commands/core/pr-create.md +0 -193
  17. package/commands/core/review.md +0 -56
  18. package/commands/core/sprint-status.md +0 -65
  19. package/commands/optional/docs-update.md +0 -200
  20. package/commands/optional/jira-create.md +0 -200
  21. package/commands/optional/jira-transition.md +0 -184
  22. package/commands/optional/worktree-cleanup.md +0 -167
  23. package/commands/optional/worktree-setup.md +0 -110
  24. package/eslint.config.js +0 -29
  25. package/jest.config.js +0 -22
  26. package/knowledge-library/README.md +0 -118
  27. package/knowledge-library/android-engineer/context/current.txt +0 -42
  28. package/knowledge-library/android-engineer/control/decisions.txt +0 -9
  29. package/knowledge-library/android-engineer/control/dependencies.txt +0 -19
  30. package/knowledge-library/android-engineer/control/objectives.txt +0 -26
  31. package/knowledge-library/android-engineer/history/.gitkeep +0 -0
  32. package/knowledge-library/android-engineer/inbox/processed/.gitkeep +0 -0
  33. package/knowledge-library/android-engineer/outbox/.gitkeep +0 -0
  34. package/knowledge-library/android-engineer/tech/.gitkeep +0 -0
  35. package/knowledge-library/architecture.txt +0 -61
  36. package/knowledge-library/backend-engineer/context/current.txt +0 -42
  37. package/knowledge-library/backend-engineer/control/decisions.txt +0 -9
  38. package/knowledge-library/backend-engineer/control/dependencies.txt +0 -19
  39. package/knowledge-library/backend-engineer/control/objectives.txt +0 -26
  40. package/knowledge-library/backend-engineer/history/.gitkeep +0 -0
  41. package/knowledge-library/backend-engineer/inbox/processed/.gitkeep +0 -0
  42. package/knowledge-library/backend-engineer/outbox/.gitkeep +0 -0
  43. package/knowledge-library/backend-engineer/tech/.gitkeep +0 -0
  44. package/knowledge-library/context.txt +0 -52
  45. package/knowledge-library/devops-engineer/context/current.txt +0 -42
  46. package/knowledge-library/devops-engineer/control/decisions.txt +0 -9
  47. package/knowledge-library/devops-engineer/control/dependencies.txt +0 -19
  48. package/knowledge-library/devops-engineer/control/objectives.txt +0 -26
  49. package/knowledge-library/devops-engineer/history/.gitkeep +0 -0
  50. package/knowledge-library/devops-engineer/inbox/processed/.gitkeep +0 -0
  51. package/knowledge-library/devops-engineer/outbox/.gitkeep +0 -0
  52. package/knowledge-library/devops-engineer/tech/.gitkeep +0 -0
  53. package/knowledge-library/engineering-manager/context/current.txt +0 -40
  54. package/knowledge-library/engineering-manager/control/decisions.txt +0 -9
  55. package/knowledge-library/engineering-manager/control/objectives.txt +0 -27
  56. package/knowledge-library/engineering-manager/history/.gitkeep +0 -0
  57. package/knowledge-library/engineering-manager/inbox/processed/.gitkeep +0 -0
  58. package/knowledge-library/engineering-manager/outbox/.gitkeep +0 -0
  59. package/knowledge-library/engineering-manager/tech/.gitkeep +0 -0
  60. package/knowledge-library/prd.txt +0 -81
  61. package/knowledge-library/product-manager/context/current.txt +0 -42
  62. package/knowledge-library/product-manager/control/decisions.txt +0 -9
  63. package/knowledge-library/product-manager/control/dependencies.txt +0 -19
  64. package/knowledge-library/product-manager/control/objectives.txt +0 -26
  65. package/knowledge-library/product-manager/history/.gitkeep +0 -0
  66. package/knowledge-library/product-manager/inbox/processed/.gitkeep +0 -0
  67. package/knowledge-library/product-manager/outbox/.gitkeep +0 -0
  68. package/knowledge-library/product-manager/tech/.gitkeep +0 -0
  69. package/knowledge-library/qa-engineer/context/current.txt +0 -42
  70. package/knowledge-library/qa-engineer/control/decisions.txt +0 -9
  71. package/knowledge-library/qa-engineer/control/dependencies.txt +0 -19
  72. package/knowledge-library/qa-engineer/control/objectives.txt +0 -26
  73. package/knowledge-library/qa-engineer/history/.gitkeep +0 -0
  74. package/knowledge-library/qa-engineer/inbox/processed/.gitkeep +0 -0
  75. package/knowledge-library/qa-engineer/outbox/.gitkeep +0 -0
  76. package/knowledge-library/qa-engineer/tech/.gitkeep +0 -0
  77. package/knowledge-library/security-engineer/context/current.txt +0 -42
  78. package/knowledge-library/security-engineer/control/decisions.txt +0 -9
  79. package/knowledge-library/security-engineer/control/dependencies.txt +0 -19
  80. package/knowledge-library/security-engineer/control/objectives.txt +0 -26
  81. package/knowledge-library/security-engineer/history/.gitkeep +0 -0
  82. package/knowledge-library/security-engineer/inbox/processed/.gitkeep +0 -0
  83. package/knowledge-library/security-engineer/outbox/.gitkeep +0 -0
  84. package/knowledge-library/security-engineer/tech/.gitkeep +0 -0
  85. package/knowledge-library/solutions-architect/context/current.txt +0 -42
  86. package/knowledge-library/solutions-architect/control/decisions.txt +0 -9
  87. package/knowledge-library/solutions-architect/control/dependencies.txt +0 -19
  88. package/knowledge-library/solutions-architect/control/objectives.txt +0 -26
  89. package/knowledge-library/solutions-architect/history/.gitkeep +0 -0
  90. package/knowledge-library/solutions-architect/inbox/processed/.gitkeep +0 -0
  91. package/knowledge-library/solutions-architect/outbox/.gitkeep +0 -0
  92. package/knowledge-library/solutions-architect/tech/.gitkeep +0 -0
  93. package/knowledge-library/wearos-engineer/context/current.txt +0 -42
  94. package/knowledge-library/wearos-engineer/control/decisions.txt +0 -9
  95. package/knowledge-library/wearos-engineer/control/dependencies.txt +0 -19
  96. package/knowledge-library/wearos-engineer/control/objectives.txt +0 -26
  97. package/knowledge-library/wearos-engineer/history/.gitkeep +0 -0
  98. package/knowledge-library/wearos-engineer/inbox/processed/.gitkeep +0 -0
  99. package/knowledge-library/wearos-engineer/outbox/.gitkeep +0 -0
  100. package/knowledge-library/wearos-engineer/tech/.gitkeep +0 -0
  101. package/scripts/add-agent.sh +0 -323
  102. package/scripts/install.sh +0 -354
  103. package/src/adapters/factory.test.ts +0 -386
  104. package/src/adapters/factory.ts +0 -305
  105. package/src/adapters/index.ts +0 -113
  106. package/src/adapters/interfaces.ts +0 -268
  107. package/src/adapters/mcp/client.test.ts +0 -130
  108. package/src/adapters/mcp/client.ts +0 -451
  109. package/src/adapters/mcp/discovery.test.ts +0 -315
  110. package/src/adapters/mcp/discovery.ts +0 -340
  111. package/src/adapters/mcp/index.ts +0 -66
  112. package/src/adapters/mcp/mapper.test.ts +0 -218
  113. package/src/adapters/mcp/mapper.ts +0 -536
  114. package/src/adapters/mcp/registry.test.ts +0 -433
  115. package/src/adapters/mcp/registry.ts +0 -550
  116. package/src/adapters/mcp/types.ts +0 -258
  117. package/src/adapters/native/filesystem.test.ts +0 -350
  118. package/src/adapters/native/filesystem.ts +0 -393
  119. package/src/adapters/native/github.test.ts +0 -173
  120. package/src/adapters/native/github.ts +0 -627
  121. package/src/adapters/native/index.ts +0 -22
  122. package/src/adapters/native/selector.test.ts +0 -224
  123. package/src/adapters/native/selector.ts +0 -150
  124. package/src/adapters/types.ts +0 -270
  125. package/src/agents/compiler.test.ts +0 -410
  126. package/src/agents/compiler.ts +0 -424
  127. package/src/agents/index.ts +0 -37
  128. package/src/agents/loader.test.ts +0 -319
  129. package/src/agents/loader.ts +0 -143
  130. package/src/agents/resolver.test.ts +0 -282
  131. package/src/agents/resolver.ts +0 -262
  132. package/src/agents/types.ts +0 -97
  133. package/src/cache/index.ts +0 -38
  134. package/src/cache/interfaces.ts +0 -283
  135. package/src/cache/manager.test.ts +0 -266
  136. package/src/cache/manager.ts +0 -388
  137. package/src/cache/provider.test.ts +0 -485
  138. package/src/cache/provider.ts +0 -745
  139. package/src/cache/types.test.ts +0 -192
  140. package/src/cache/types.ts +0 -313
  141. package/src/cli/commands/build.test.ts +0 -248
  142. package/src/cli/commands/build.ts +0 -284
  143. package/src/cli/commands/cache.test.ts +0 -221
  144. package/src/cli/commands/cache.ts +0 -229
  145. package/src/cli/commands/index.ts +0 -63
  146. package/src/cli/commands/init.test.ts +0 -173
  147. package/src/cli/commands/init.ts +0 -296
  148. package/src/cli/commands/skills.test.ts +0 -272
  149. package/src/cli/commands/skills.ts +0 -348
  150. package/src/cli/commands/status.test.ts +0 -392
  151. package/src/cli/commands/status.ts +0 -332
  152. package/src/cli/commands/sync.test.ts +0 -213
  153. package/src/cli/commands/sync.ts +0 -251
  154. package/src/cli/commands/validate.test.ts +0 -216
  155. package/src/cli/commands/validate.ts +0 -340
  156. package/src/cli/index.test.ts +0 -190
  157. package/src/cli/index.ts +0 -493
  158. package/src/commands/context.test.ts +0 -163
  159. package/src/commands/context.ts +0 -111
  160. package/src/commands/index.ts +0 -56
  161. package/src/commands/loader.test.ts +0 -273
  162. package/src/commands/loader.ts +0 -355
  163. package/src/commands/registry.test.ts +0 -384
  164. package/src/commands/registry.ts +0 -248
  165. package/src/commands/runner.test.ts +0 -297
  166. package/src/commands/runner.ts +0 -222
  167. package/src/commands/types.ts +0 -361
  168. package/src/config/index.ts +0 -19
  169. package/src/config/loader.test.ts +0 -262
  170. package/src/config/loader.ts +0 -188
  171. package/src/config/types.ts +0 -154
  172. package/src/context/index.ts +0 -14
  173. package/src/context/loader.test.ts +0 -334
  174. package/src/context/loader.ts +0 -357
  175. package/src/index.test.ts +0 -13
  176. package/src/index.ts +0 -268
  177. package/src/knowledge-library/index.ts +0 -44
  178. package/src/knowledge-library/manager.test.ts +0 -536
  179. package/src/knowledge-library/manager.ts +0 -804
  180. package/src/knowledge-library/types.ts +0 -432
  181. package/src/skills/generator.test.ts +0 -602
  182. package/src/skills/generator.ts +0 -491
  183. package/src/skills/index.ts +0 -27
  184. package/src/skills/templates.ts +0 -520
  185. package/src/skills/types.ts +0 -251
  186. package/templates/completion-report.md +0 -72
  187. package/templates/feedback.md +0 -56
  188. package/templates/project-files/CLAUDE.md.template +0 -109
  189. package/templates/project-files/coreai.json.example +0 -47
  190. package/templates/project-files/mcp.json.template +0 -20
  191. package/templates/review-complete.md +0 -64
  192. package/templates/review-request.md +0 -67
  193. package/templates/task-assignment.md +0 -51
  194. package/tsconfig.build.json +0 -4
  195. package/tsconfig.json +0 -26
  196. package/tsup.config.ts +0 -23
@@ -1,315 +0,0 @@
1
- import { mkdtempSync, writeFileSync, rmSync, mkdirSync } from 'fs';
2
- import { join } from 'path';
3
- import { tmpdir } from 'os';
4
- import {
5
- discoverMcpServers,
6
- loadServersFromFile,
7
- parseServersFromConfig,
8
- validateServerConfig,
9
- findMcpConfigFile,
10
- getDefaultMcpConfigPath,
11
- } from './discovery.js';
12
- import { McpError } from './types.js';
13
-
14
- describe('MCP Discovery', () => {
15
- let tempDir: string;
16
-
17
- beforeEach(() => {
18
- tempDir = mkdtempSync(join(tmpdir(), 'mcp-discovery-test-'));
19
- });
20
-
21
- afterEach(() => {
22
- rmSync(tempDir, { recursive: true, force: true });
23
- });
24
-
25
- describe('validateServerConfig', () => {
26
- it('should validate stdio config with command', () => {
27
- const config = validateServerConfig(
28
- {
29
- command: 'node',
30
- args: ['server.js'],
31
- },
32
- 'test-server'
33
- );
34
-
35
- expect(config.transport).toBe('stdio');
36
- expect(config).toEqual({
37
- transport: 'stdio',
38
- command: 'node',
39
- args: ['server.js'],
40
- });
41
- });
42
-
43
- it('should validate stdio config with explicit transport', () => {
44
- const config = validateServerConfig(
45
- {
46
- transport: 'stdio',
47
- command: 'npx',
48
- args: ['-y', '@modelcontextprotocol/server-github'],
49
- env: { GITHUB_TOKEN: 'xxx' },
50
- },
51
- 'github'
52
- );
53
-
54
- expect(config.transport).toBe('stdio');
55
- expect((config as { command: string }).command).toBe('npx');
56
- expect((config as { args: string[] }).args).toEqual([
57
- '-y',
58
- '@modelcontextprotocol/server-github',
59
- ]);
60
- expect((config as { env: Record<string, string> }).env).toEqual({ GITHUB_TOKEN: 'xxx' });
61
- });
62
-
63
- it('should validate http config with url', () => {
64
- const config = validateServerConfig(
65
- {
66
- url: 'https://api.example.com/mcp',
67
- },
68
- 'remote-server'
69
- );
70
-
71
- expect(config.transport).toBe('http');
72
- expect((config as { url: string }).url).toBe('https://api.example.com/mcp');
73
- });
74
-
75
- it('should validate sse config with explicit transport', () => {
76
- const config = validateServerConfig(
77
- {
78
- transport: 'sse',
79
- url: 'https://api.example.com/sse',
80
- headers: { Authorization: 'Bearer xxx' },
81
- },
82
- 'sse-server'
83
- );
84
-
85
- expect(config.transport).toBe('sse');
86
- });
87
-
88
- it('should throw for missing command or url', () => {
89
- expect(() => validateServerConfig({}, 'test')).toThrow(McpError);
90
- });
91
-
92
- it('should throw for invalid url', () => {
93
- expect(() => validateServerConfig({ url: 'not-a-url' }, 'test')).toThrow(McpError);
94
- });
95
-
96
- it('should throw for invalid args type', () => {
97
- expect(() => validateServerConfig({ command: 'node', args: 'invalid' }, 'test')).toThrow(
98
- McpError
99
- );
100
- });
101
- });
102
-
103
- describe('parseServersFromConfig', () => {
104
- it('should parse servers from config object', () => {
105
- const config = {
106
- mcpServers: {
107
- github: {
108
- command: 'npx',
109
- args: ['-y', '@modelcontextprotocol/server-github'],
110
- },
111
- filesystem: {
112
- command: 'npx',
113
- args: ['-y', '@modelcontextprotocol/server-filesystem'],
114
- },
115
- },
116
- };
117
-
118
- const servers = parseServersFromConfig(config);
119
-
120
- expect(servers).toHaveLength(2);
121
- expect(servers.map((s) => s.name)).toContain('github');
122
- expect(servers.map((s) => s.name)).toContain('filesystem');
123
- });
124
-
125
- it('should return empty array for config without mcpServers', () => {
126
- const servers = parseServersFromConfig({});
127
- expect(servers).toHaveLength(0);
128
- });
129
-
130
- it('should skip invalid server configs', () => {
131
- const config = {
132
- mcpServers: {
133
- valid: { command: 'node' },
134
- invalid: { invalid: true },
135
- },
136
- };
137
-
138
- const servers = parseServersFromConfig(config);
139
- expect(servers).toHaveLength(1);
140
- expect(servers[0].name).toBe('valid');
141
- });
142
- });
143
-
144
- describe('loadServersFromFile', () => {
145
- it('should load servers from JSON file', () => {
146
- const configPath = join(tempDir, 'mcp.json');
147
- writeFileSync(
148
- configPath,
149
- JSON.stringify({
150
- mcpServers: {
151
- 'test-server': {
152
- command: 'node',
153
- args: ['server.js'],
154
- },
155
- },
156
- })
157
- );
158
-
159
- const servers = loadServersFromFile(configPath);
160
-
161
- expect(servers).toHaveLength(1);
162
- expect(servers[0].name).toBe('test-server');
163
- expect(servers[0].config.transport).toBe('stdio');
164
- });
165
-
166
- it('should throw for non-existent file', () => {
167
- expect(() => loadServersFromFile('/nonexistent/file.json')).toThrow(McpError);
168
- });
169
-
170
- it('should throw for invalid JSON', () => {
171
- const configPath = join(tempDir, 'invalid.json');
172
- writeFileSync(configPath, 'not valid json');
173
-
174
- expect(() => loadServersFromFile(configPath)).toThrow(McpError);
175
- });
176
- });
177
-
178
- describe('discoverMcpServers', () => {
179
- it('should discover servers from project directory', () => {
180
- // Create project with .claude/mcp.json
181
- const claudeDir = join(tempDir, '.claude');
182
- mkdirSync(claudeDir);
183
- writeFileSync(
184
- join(claudeDir, 'mcp.json'),
185
- JSON.stringify({
186
- mcpServers: {
187
- project: { command: 'node', args: ['project-server.js'] },
188
- },
189
- })
190
- );
191
-
192
- const servers = discoverMcpServers({
193
- projectRoot: tempDir,
194
- includeGlobal: false,
195
- });
196
-
197
- expect(servers).toHaveLength(1);
198
- expect(servers[0].name).toBe('project');
199
- });
200
-
201
- it('should discover from root mcp.json', () => {
202
- writeFileSync(
203
- join(tempDir, 'mcp.json'),
204
- JSON.stringify({
205
- mcpServers: {
206
- root: { command: 'node' },
207
- },
208
- })
209
- );
210
-
211
- const servers = discoverMcpServers({
212
- projectRoot: tempDir,
213
- includeGlobal: false,
214
- });
215
-
216
- expect(servers).toHaveLength(1);
217
- expect(servers[0].name).toBe('root');
218
- });
219
-
220
- it('should prioritize project config over root config', () => {
221
- // Create both configs with same server name
222
- const claudeDir = join(tempDir, '.claude');
223
- mkdirSync(claudeDir);
224
- writeFileSync(
225
- join(claudeDir, 'mcp.json'),
226
- JSON.stringify({
227
- mcpServers: {
228
- shared: { command: 'project-cmd' },
229
- },
230
- })
231
- );
232
- writeFileSync(
233
- join(tempDir, 'mcp.json'),
234
- JSON.stringify({
235
- mcpServers: {
236
- shared: { command: 'root-cmd' },
237
- },
238
- })
239
- );
240
-
241
- const servers = discoverMcpServers({
242
- projectRoot: tempDir,
243
- includeGlobal: false,
244
- });
245
-
246
- expect(servers).toHaveLength(1);
247
- expect((servers[0].config as { command: string }).command).toBe('project-cmd');
248
- });
249
-
250
- it('should discover from additional paths', () => {
251
- const customPath = join(tempDir, 'custom', 'config.json');
252
- mkdirSync(join(tempDir, 'custom'));
253
- writeFileSync(
254
- customPath,
255
- JSON.stringify({
256
- mcpServers: {
257
- custom: { command: 'custom-cmd' },
258
- },
259
- })
260
- );
261
-
262
- const servers = discoverMcpServers({
263
- projectRoot: tempDir,
264
- includeGlobal: false,
265
- additionalPaths: [customPath],
266
- });
267
-
268
- expect(servers.some((s) => s.name === 'custom')).toBe(true);
269
- });
270
-
271
- it('should return empty array when no configs found', () => {
272
- const servers = discoverMcpServers({
273
- projectRoot: tempDir,
274
- includeGlobal: false,
275
- });
276
-
277
- expect(servers).toHaveLength(0);
278
- });
279
- });
280
-
281
- describe('findMcpConfigFile', () => {
282
- it('should find config in .claude directory', () => {
283
- const claudeDir = join(tempDir, '.claude');
284
- mkdirSync(claudeDir);
285
- writeFileSync(join(claudeDir, 'mcp.json'), '{}');
286
-
287
- const found = findMcpConfigFile(tempDir);
288
- expect(found).toBe(join(claudeDir, 'mcp.json'));
289
- });
290
-
291
- it('should find config in root directory', () => {
292
- writeFileSync(join(tempDir, 'mcp.json'), '{}');
293
-
294
- const found = findMcpConfigFile(tempDir);
295
- expect(found).toBe(join(tempDir, 'mcp.json'));
296
- });
297
-
298
- it('should return null when no config found', () => {
299
- const found = findMcpConfigFile(tempDir);
300
- expect(found).toBeNull();
301
- });
302
- });
303
-
304
- describe('getDefaultMcpConfigPath', () => {
305
- it('should return .claude/mcp.json path', () => {
306
- const path = getDefaultMcpConfigPath(tempDir);
307
- expect(path).toBe(join(tempDir, '.claude', 'mcp.json'));
308
- });
309
-
310
- it('should use cwd when no root provided', () => {
311
- const path = getDefaultMcpConfigPath();
312
- expect(path).toBe(join(process.cwd(), '.claude', 'mcp.json'));
313
- });
314
- });
315
- });
@@ -1,340 +0,0 @@
1
- /**
2
- * MCP Server Discovery
3
- *
4
- * Discovers and loads MCP server configurations from various sources.
5
- */
6
-
7
- import { existsSync, readFileSync } from 'fs';
8
- import { join, dirname } from 'path';
9
- import { homedir } from 'os';
10
- import type {
11
- McpConfigFile,
12
- McpServerConfig,
13
- McpServerDefinition,
14
- StdioServerConfig,
15
- HttpServerConfig,
16
- } from './types.js';
17
- import { McpError } from './types.js';
18
-
19
- /**
20
- * Options for discovering MCP servers
21
- */
22
- export interface DiscoveryOptions {
23
- /**
24
- * Project root directory to search from
25
- */
26
- projectRoot?: string;
27
-
28
- /**
29
- * Whether to include global config from home directory
30
- */
31
- includeGlobal?: boolean;
32
-
33
- /**
34
- * Additional config file paths to check
35
- */
36
- additionalPaths?: string[];
37
- }
38
-
39
- /**
40
- * Known config file locations
41
- */
42
- const CONFIG_FILENAMES = ['mcp.json', '.mcp.json', 'claude_desktop_config.json'];
43
-
44
- const PROJECT_CONFIG_DIRS = ['.claude', '.config', ''];
45
-
46
- /**
47
- * Discover MCP servers from configuration files
48
- */
49
- export function discoverMcpServers(options: DiscoveryOptions = {}): McpServerDefinition[] {
50
- const projectRoot = options.projectRoot ?? process.cwd();
51
- const includeGlobal = options.includeGlobal ?? true;
52
- const additionalPaths = options.additionalPaths ?? [];
53
-
54
- const servers: McpServerDefinition[] = [];
55
- const seenServers = new Set<string>();
56
-
57
- // Build list of config file paths to check
58
- const configPaths: string[] = [];
59
-
60
- // Project-level configs (highest priority)
61
- for (const dir of PROJECT_CONFIG_DIRS) {
62
- for (const filename of CONFIG_FILENAMES) {
63
- const path = dir ? join(projectRoot, dir, filename) : join(projectRoot, filename);
64
- configPaths.push(path);
65
- }
66
- }
67
-
68
- // Additional paths
69
- configPaths.push(...additionalPaths);
70
-
71
- // Global config (lowest priority)
72
- if (includeGlobal) {
73
- const homeDir = homedir();
74
- const globalPaths = [
75
- join(homeDir, '.config', 'claude', 'mcp.json'),
76
- join(homeDir, '.claude', 'mcp.json'),
77
- join(homeDir, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'),
78
- ];
79
- configPaths.push(...globalPaths);
80
- }
81
-
82
- // Load servers from each config file (earlier files take precedence)
83
- for (const configPath of configPaths) {
84
- if (!existsSync(configPath)) continue;
85
-
86
- try {
87
- const fileServers = loadServersFromFile(configPath);
88
-
89
- for (const server of fileServers) {
90
- // Skip if we already have a server with this name
91
- if (seenServers.has(server.name)) continue;
92
-
93
- seenServers.add(server.name);
94
- servers.push(server);
95
- }
96
- } catch (error) {
97
- // Log warning but continue with other files
98
- console.warn(
99
- `Warning: Failed to load MCP config from ${configPath}: ${error instanceof Error ? error.message : String(error)}`
100
- );
101
- }
102
- }
103
-
104
- return servers;
105
- }
106
-
107
- /**
108
- * Load MCP servers from a config file
109
- */
110
- export function loadServersFromFile(filePath: string): McpServerDefinition[] {
111
- if (!existsSync(filePath)) {
112
- throw new McpError(`Config file not found: ${filePath}`, 'invalid_config');
113
- }
114
-
115
- const content = readFileSync(filePath, 'utf-8');
116
- let config: McpConfigFile;
117
-
118
- try {
119
- config = JSON.parse(content);
120
- } catch (error) {
121
- throw new McpError(
122
- `Invalid JSON in config file ${filePath}: ${error instanceof Error ? error.message : String(error)}`,
123
- 'invalid_config',
124
- undefined,
125
- error instanceof Error ? error : undefined
126
- );
127
- }
128
-
129
- return parseServersFromConfig(config, filePath);
130
- }
131
-
132
- /**
133
- * Parse server definitions from config object
134
- */
135
- export function parseServersFromConfig(
136
- config: McpConfigFile,
137
- sourcePath?: string
138
- ): McpServerDefinition[] {
139
- const servers: McpServerDefinition[] = [];
140
-
141
- if (!config.mcpServers) {
142
- return servers;
143
- }
144
-
145
- for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
146
- try {
147
- const validConfig = validateServerConfig(serverConfig, name);
148
-
149
- // Resolve relative paths for stdio commands
150
- if (validConfig.transport === 'stdio' && sourcePath) {
151
- validConfig.cwd = validConfig.cwd ?? dirname(sourcePath);
152
- }
153
-
154
- servers.push({
155
- name,
156
- config: validConfig,
157
- enabled: true,
158
- });
159
- } catch (error) {
160
- console.warn(
161
- `Warning: Invalid server config for "${name}": ${error instanceof Error ? error.message : String(error)}`
162
- );
163
- }
164
- }
165
-
166
- return servers;
167
- }
168
-
169
- /**
170
- * Validate and normalize a server configuration
171
- */
172
- export function validateServerConfig(config: unknown, serverName: string): McpServerConfig {
173
- if (!config || typeof config !== 'object') {
174
- throw new McpError(
175
- `Server config for "${serverName}" must be an object`,
176
- 'invalid_config',
177
- serverName
178
- );
179
- }
180
-
181
- const cfg = config as Record<string, unknown>;
182
-
183
- // Determine transport type
184
- // If 'command' exists, it's stdio
185
- // If 'url' exists, it's http/sse
186
- // Otherwise check explicit 'transport' field
187
-
188
- if ('command' in cfg && typeof cfg.command === 'string') {
189
- return validateStdioConfig(cfg, serverName);
190
- }
191
-
192
- if ('url' in cfg && typeof cfg.url === 'string') {
193
- return validateHttpConfig(cfg, serverName);
194
- }
195
-
196
- // Check explicit transport
197
- if ('transport' in cfg) {
198
- const transport = cfg.transport;
199
- if (transport === 'stdio') {
200
- return validateStdioConfig(cfg, serverName);
201
- }
202
- if (transport === 'http' || transport === 'sse') {
203
- return validateHttpConfig(cfg, serverName);
204
- }
205
- throw new McpError(
206
- `Unknown transport type "${transport}" for server "${serverName}"`,
207
- 'invalid_config',
208
- serverName
209
- );
210
- }
211
-
212
- throw new McpError(
213
- `Server config for "${serverName}" must have either 'command' (stdio) or 'url' (http)`,
214
- 'invalid_config',
215
- serverName
216
- );
217
- }
218
-
219
- /**
220
- * Validate stdio server configuration
221
- */
222
- function validateStdioConfig(cfg: Record<string, unknown>, serverName: string): StdioServerConfig {
223
- if (!cfg.command || typeof cfg.command !== 'string') {
224
- throw new McpError(
225
- `Server "${serverName}" requires a 'command' string`,
226
- 'invalid_config',
227
- serverName
228
- );
229
- }
230
-
231
- const config: StdioServerConfig = {
232
- transport: 'stdio',
233
- command: cfg.command,
234
- };
235
-
236
- if (cfg.args !== undefined) {
237
- if (!Array.isArray(cfg.args) || !cfg.args.every((a) => typeof a === 'string')) {
238
- throw new McpError(
239
- `Server "${serverName}" 'args' must be an array of strings`,
240
- 'invalid_config',
241
- serverName
242
- );
243
- }
244
- config.args = cfg.args;
245
- }
246
-
247
- if (cfg.env !== undefined) {
248
- if (typeof cfg.env !== 'object' || cfg.env === null) {
249
- throw new McpError(
250
- `Server "${serverName}" 'env' must be an object`,
251
- 'invalid_config',
252
- serverName
253
- );
254
- }
255
- config.env = cfg.env as Record<string, string>;
256
- }
257
-
258
- if (cfg.cwd !== undefined) {
259
- if (typeof cfg.cwd !== 'string') {
260
- throw new McpError(
261
- `Server "${serverName}" 'cwd' must be a string`,
262
- 'invalid_config',
263
- serverName
264
- );
265
- }
266
- config.cwd = cfg.cwd;
267
- }
268
-
269
- return config;
270
- }
271
-
272
- /**
273
- * Validate HTTP/SSE server configuration
274
- */
275
- function validateHttpConfig(cfg: Record<string, unknown>, serverName: string): HttpServerConfig {
276
- if (!cfg.url || typeof cfg.url !== 'string') {
277
- throw new McpError(
278
- `Server "${serverName}" requires a 'url' string`,
279
- 'invalid_config',
280
- serverName
281
- );
282
- }
283
-
284
- // Validate URL
285
- try {
286
- new URL(cfg.url);
287
- } catch {
288
- throw new McpError(
289
- `Server "${serverName}" has invalid URL: ${cfg.url}`,
290
- 'invalid_config',
291
- serverName
292
- );
293
- }
294
-
295
- const transport = cfg.transport === 'sse' ? 'sse' : 'http';
296
-
297
- const config: HttpServerConfig = {
298
- transport,
299
- url: cfg.url,
300
- };
301
-
302
- if (cfg.headers !== undefined) {
303
- if (typeof cfg.headers !== 'object' || cfg.headers === null) {
304
- throw new McpError(
305
- `Server "${serverName}" 'headers' must be an object`,
306
- 'invalid_config',
307
- serverName
308
- );
309
- }
310
- config.headers = cfg.headers as Record<string, string>;
311
- }
312
-
313
- return config;
314
- }
315
-
316
- /**
317
- * Find an MCP config file in the project
318
- */
319
- export function findMcpConfigFile(projectRoot?: string): string | null {
320
- const root = projectRoot ?? process.cwd();
321
-
322
- for (const dir of PROJECT_CONFIG_DIRS) {
323
- for (const filename of CONFIG_FILENAMES) {
324
- const path = dir ? join(root, dir, filename) : join(root, filename);
325
- if (existsSync(path)) {
326
- return path;
327
- }
328
- }
329
- }
330
-
331
- return null;
332
- }
333
-
334
- /**
335
- * Get the default MCP config path for a project
336
- */
337
- export function getDefaultMcpConfigPath(projectRoot?: string): string {
338
- const root = projectRoot ?? process.cwd();
339
- return join(root, '.claude', 'mcp.json');
340
- }
@@ -1,66 +0,0 @@
1
- /**
2
- * MCP Integration Module
3
- *
4
- * Provides MCP (Model Context Protocol) integration for adapters.
5
- */
6
-
7
- // Types
8
- export type {
9
- McpTransportType,
10
- StdioServerConfig,
11
- HttpServerConfig,
12
- McpServerConfig,
13
- McpServerDefinition,
14
- McpConfigFile,
15
- McpServerInfo,
16
- McpCapabilities,
17
- McpTool,
18
- McpResource,
19
- McpToolResult,
20
- McpContent,
21
- McpTextContent,
22
- McpImageContent,
23
- McpResourceContent,
24
- McpErrorCode,
25
- } from './types.js';
26
-
27
- export { McpError } from './types.js';
28
-
29
- // Client
30
- export type { McpClientOptions } from './client.js';
31
-
32
- export { McpClient, createMockMcpClient } from './client.js';
33
-
34
- // Discovery
35
- export type { DiscoveryOptions } from './discovery.js';
36
-
37
- export {
38
- discoverMcpServers,
39
- loadServersFromFile,
40
- parseServersFromConfig,
41
- validateServerConfig,
42
- findMcpConfigFile,
43
- getDefaultMcpConfigPath,
44
- } from './discovery.js';
45
-
46
- // Mapper
47
- export type { ToolMapping, ServerMapping } from './mapper.js';
48
-
49
- export {
50
- findKnownServerMappings,
51
- autoDiscoverMappings,
52
- getMappingsForServer,
53
- groupMappingsByAdapter,
54
- } from './mapper.js';
55
-
56
- // Registry
57
- export type {
58
- ServerEntry,
59
- ServerStatus,
60
- RegistryEvents,
61
- RegistryOptions,
62
- ServerStatusSummary,
63
- RegistryStatus,
64
- } from './registry.js';
65
-
66
- export { McpRegistry, createRegistry } from './registry.js';