@open-mercato/ai-assistant 0.4.2-canary-c02407ff85

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 (193) hide show
  1. package/AGENTS.md +1090 -0
  2. package/README.md +607 -0
  3. package/build.mjs +92 -0
  4. package/dist/di.js +8 -0
  5. package/dist/di.js.map +7 -0
  6. package/dist/frontend/components/CommandPalette/CommandFooter.js +80 -0
  7. package/dist/frontend/components/CommandPalette/CommandFooter.js.map +7 -0
  8. package/dist/frontend/components/CommandPalette/CommandHeader.js +53 -0
  9. package/dist/frontend/components/CommandPalette/CommandHeader.js.map +7 -0
  10. package/dist/frontend/components/CommandPalette/CommandInput.js +29 -0
  11. package/dist/frontend/components/CommandPalette/CommandInput.js.map +7 -0
  12. package/dist/frontend/components/CommandPalette/CommandItem.js +92 -0
  13. package/dist/frontend/components/CommandPalette/CommandItem.js.map +7 -0
  14. package/dist/frontend/components/CommandPalette/CommandPalette.js +244 -0
  15. package/dist/frontend/components/CommandPalette/CommandPalette.js.map +7 -0
  16. package/dist/frontend/components/CommandPalette/CommandPaletteProvider.js +42 -0
  17. package/dist/frontend/components/CommandPalette/CommandPaletteProvider.js.map +7 -0
  18. package/dist/frontend/components/CommandPalette/CommandPaletteWrapper.js +18 -0
  19. package/dist/frontend/components/CommandPalette/CommandPaletteWrapper.js.map +7 -0
  20. package/dist/frontend/components/CommandPalette/DebugPanel.js +215 -0
  21. package/dist/frontend/components/CommandPalette/DebugPanel.js.map +7 -0
  22. package/dist/frontend/components/CommandPalette/MessageBubble.js +64 -0
  23. package/dist/frontend/components/CommandPalette/MessageBubble.js.map +7 -0
  24. package/dist/frontend/components/CommandPalette/ToolCallConfirmation.js +91 -0
  25. package/dist/frontend/components/CommandPalette/ToolCallConfirmation.js.map +7 -0
  26. package/dist/frontend/components/CommandPalette/ToolCallDisplay.js +47 -0
  27. package/dist/frontend/components/CommandPalette/ToolCallDisplay.js.map +7 -0
  28. package/dist/frontend/components/CommandPalette/ToolChatPage.js +74 -0
  29. package/dist/frontend/components/CommandPalette/ToolChatPage.js.map +7 -0
  30. package/dist/frontend/components/CommandPalette/index.js +28 -0
  31. package/dist/frontend/components/CommandPalette/index.js.map +7 -0
  32. package/dist/frontend/constants.js +41 -0
  33. package/dist/frontend/constants.js.map +7 -0
  34. package/dist/frontend/hooks/index.js +13 -0
  35. package/dist/frontend/hooks/index.js.map +7 -0
  36. package/dist/frontend/hooks/useCommandPalette.js +1094 -0
  37. package/dist/frontend/hooks/useCommandPalette.js.map +7 -0
  38. package/dist/frontend/hooks/useMcpTools.js +66 -0
  39. package/dist/frontend/hooks/useMcpTools.js.map +7 -0
  40. package/dist/frontend/hooks/usePageContext.js +48 -0
  41. package/dist/frontend/hooks/usePageContext.js.map +7 -0
  42. package/dist/frontend/hooks/useRecentActions.js +56 -0
  43. package/dist/frontend/hooks/useRecentActions.js.map +7 -0
  44. package/dist/frontend/hooks/useRecentTools.js +55 -0
  45. package/dist/frontend/hooks/useRecentTools.js.map +7 -0
  46. package/dist/frontend/index.js +35 -0
  47. package/dist/frontend/index.js.map +7 -0
  48. package/dist/frontend/types.js +1 -0
  49. package/dist/frontend/types.js.map +7 -0
  50. package/dist/frontend/utils/index.js +7 -0
  51. package/dist/frontend/utils/index.js.map +7 -0
  52. package/dist/frontend/utils/toolMatcher.js +95 -0
  53. package/dist/frontend/utils/toolMatcher.js.map +7 -0
  54. package/dist/index.js +57 -0
  55. package/dist/index.js.map +7 -0
  56. package/dist/modules/ai_assistant/acl.js +14 -0
  57. package/dist/modules/ai_assistant/acl.js.map +7 -0
  58. package/dist/modules/ai_assistant/api/chat/route.js +152 -0
  59. package/dist/modules/ai_assistant/api/chat/route.js.map +7 -0
  60. package/dist/modules/ai_assistant/api/health/route.js +27 -0
  61. package/dist/modules/ai_assistant/api/health/route.js.map +7 -0
  62. package/dist/modules/ai_assistant/api/route/route.js +123 -0
  63. package/dist/modules/ai_assistant/api/route/route.js.map +7 -0
  64. package/dist/modules/ai_assistant/api/settings/route.js +60 -0
  65. package/dist/modules/ai_assistant/api/settings/route.js.map +7 -0
  66. package/dist/modules/ai_assistant/api/tools/execute/route.js +58 -0
  67. package/dist/modules/ai_assistant/api/tools/execute/route.js.map +7 -0
  68. package/dist/modules/ai_assistant/api/tools/route.js +48 -0
  69. package/dist/modules/ai_assistant/api/tools/route.js.map +7 -0
  70. package/dist/modules/ai_assistant/backend/config/ai-assistant/page.js +10 -0
  71. package/dist/modules/ai_assistant/backend/config/ai-assistant/page.js.map +7 -0
  72. package/dist/modules/ai_assistant/backend/config/ai-assistant/page.meta.js +28 -0
  73. package/dist/modules/ai_assistant/backend/config/ai-assistant/page.meta.js.map +7 -0
  74. package/dist/modules/ai_assistant/cli.js +192 -0
  75. package/dist/modules/ai_assistant/cli.js.map +7 -0
  76. package/dist/modules/ai_assistant/di.js +11 -0
  77. package/dist/modules/ai_assistant/di.js.map +7 -0
  78. package/dist/modules/ai_assistant/frontend/components/AiAssistantSettingsPageClient.js +257 -0
  79. package/dist/modules/ai_assistant/frontend/components/AiAssistantSettingsPageClient.js.map +7 -0
  80. package/dist/modules/ai_assistant/index.js +13 -0
  81. package/dist/modules/ai_assistant/index.js.map +7 -0
  82. package/dist/modules/ai_assistant/lib/ai-sdk.js +13 -0
  83. package/dist/modules/ai_assistant/lib/ai-sdk.js.map +7 -0
  84. package/dist/modules/ai_assistant/lib/api-discovery-tools.js +249 -0
  85. package/dist/modules/ai_assistant/lib/api-discovery-tools.js.map +7 -0
  86. package/dist/modules/ai_assistant/lib/api-endpoint-index-config.js +177 -0
  87. package/dist/modules/ai_assistant/lib/api-endpoint-index-config.js.map +7 -0
  88. package/dist/modules/ai_assistant/lib/api-endpoint-index.js +210 -0
  89. package/dist/modules/ai_assistant/lib/api-endpoint-index.js.map +7 -0
  90. package/dist/modules/ai_assistant/lib/auth.js +87 -0
  91. package/dist/modules/ai_assistant/lib/auth.js.map +7 -0
  92. package/dist/modules/ai_assistant/lib/chat-config.js +117 -0
  93. package/dist/modules/ai_assistant/lib/chat-config.js.map +7 -0
  94. package/dist/modules/ai_assistant/lib/client-factory.js +60 -0
  95. package/dist/modules/ai_assistant/lib/client-factory.js.map +7 -0
  96. package/dist/modules/ai_assistant/lib/http-server.js +367 -0
  97. package/dist/modules/ai_assistant/lib/http-server.js.map +7 -0
  98. package/dist/modules/ai_assistant/lib/in-process-client.js +126 -0
  99. package/dist/modules/ai_assistant/lib/in-process-client.js.map +7 -0
  100. package/dist/modules/ai_assistant/lib/mcp-client.js +146 -0
  101. package/dist/modules/ai_assistant/lib/mcp-client.js.map +7 -0
  102. package/dist/modules/ai_assistant/lib/mcp-dev-server.js +283 -0
  103. package/dist/modules/ai_assistant/lib/mcp-dev-server.js.map +7 -0
  104. package/dist/modules/ai_assistant/lib/mcp-server-config.js +160 -0
  105. package/dist/modules/ai_assistant/lib/mcp-server-config.js.map +7 -0
  106. package/dist/modules/ai_assistant/lib/mcp-server.js +156 -0
  107. package/dist/modules/ai_assistant/lib/mcp-server.js.map +7 -0
  108. package/dist/modules/ai_assistant/lib/mcp-tool-adapter.js +44 -0
  109. package/dist/modules/ai_assistant/lib/mcp-tool-adapter.js.map +7 -0
  110. package/dist/modules/ai_assistant/lib/opencode-client.js +247 -0
  111. package/dist/modules/ai_assistant/lib/opencode-client.js.map +7 -0
  112. package/dist/modules/ai_assistant/lib/opencode-handlers.js +398 -0
  113. package/dist/modules/ai_assistant/lib/opencode-handlers.js.map +7 -0
  114. package/dist/modules/ai_assistant/lib/schema-utils.js +94 -0
  115. package/dist/modules/ai_assistant/lib/schema-utils.js.map +7 -0
  116. package/dist/modules/ai_assistant/lib/tool-executor.js +55 -0
  117. package/dist/modules/ai_assistant/lib/tool-executor.js.map +7 -0
  118. package/dist/modules/ai_assistant/lib/tool-index-config.js +125 -0
  119. package/dist/modules/ai_assistant/lib/tool-index-config.js.map +7 -0
  120. package/dist/modules/ai_assistant/lib/tool-loader.js +88 -0
  121. package/dist/modules/ai_assistant/lib/tool-loader.js.map +7 -0
  122. package/dist/modules/ai_assistant/lib/tool-registry.js +65 -0
  123. package/dist/modules/ai_assistant/lib/tool-registry.js.map +7 -0
  124. package/dist/modules/ai_assistant/lib/tool-search.js +192 -0
  125. package/dist/modules/ai_assistant/lib/tool-search.js.map +7 -0
  126. package/dist/modules/ai_assistant/lib/types.js +1 -0
  127. package/dist/modules/ai_assistant/lib/types.js.map +7 -0
  128. package/package.json +108 -0
  129. package/src/di.ts +11 -0
  130. package/src/frontend/components/CommandPalette/CommandFooter.tsx +113 -0
  131. package/src/frontend/components/CommandPalette/CommandHeader.tsx +76 -0
  132. package/src/frontend/components/CommandPalette/CommandInput.tsx +50 -0
  133. package/src/frontend/components/CommandPalette/CommandItem.tsx +111 -0
  134. package/src/frontend/components/CommandPalette/CommandPalette.tsx +276 -0
  135. package/src/frontend/components/CommandPalette/CommandPaletteProvider.tsx +60 -0
  136. package/src/frontend/components/CommandPalette/CommandPaletteWrapper.tsx +21 -0
  137. package/src/frontend/components/CommandPalette/DebugPanel.tsx +257 -0
  138. package/src/frontend/components/CommandPalette/MessageBubble.tsx +73 -0
  139. package/src/frontend/components/CommandPalette/ToolCallConfirmation.tsx +130 -0
  140. package/src/frontend/components/CommandPalette/ToolCallDisplay.tsx +57 -0
  141. package/src/frontend/components/CommandPalette/ToolChatPage.tsx +125 -0
  142. package/src/frontend/components/CommandPalette/index.ts +14 -0
  143. package/src/frontend/constants.ts +35 -0
  144. package/src/frontend/hooks/index.ts +5 -0
  145. package/src/frontend/hooks/useCommandPalette.ts +1389 -0
  146. package/src/frontend/hooks/useMcpTools.ts +73 -0
  147. package/src/frontend/hooks/usePageContext.ts +61 -0
  148. package/src/frontend/hooks/useRecentActions.ts +64 -0
  149. package/src/frontend/hooks/useRecentTools.ts +69 -0
  150. package/src/frontend/index.ts +39 -0
  151. package/src/frontend/types.ts +260 -0
  152. package/src/frontend/utils/index.ts +1 -0
  153. package/src/frontend/utils/toolMatcher.ts +127 -0
  154. package/src/index.ts +92 -0
  155. package/src/modules/ai_assistant/acl.ts +10 -0
  156. package/src/modules/ai_assistant/api/chat/route.ts +213 -0
  157. package/src/modules/ai_assistant/api/health/route.ts +30 -0
  158. package/src/modules/ai_assistant/api/route/route.ts +149 -0
  159. package/src/modules/ai_assistant/api/settings/route.ts +73 -0
  160. package/src/modules/ai_assistant/api/tools/execute/route.ts +71 -0
  161. package/src/modules/ai_assistant/api/tools/route.ts +57 -0
  162. package/src/modules/ai_assistant/backend/config/ai-assistant/page.meta.ts +26 -0
  163. package/src/modules/ai_assistant/backend/config/ai-assistant/page.tsx +12 -0
  164. package/src/modules/ai_assistant/cli.ts +233 -0
  165. package/src/modules/ai_assistant/di.ts +9 -0
  166. package/src/modules/ai_assistant/frontend/components/AiAssistantSettingsPageClient.tsx +418 -0
  167. package/src/modules/ai_assistant/index.ts +11 -0
  168. package/src/modules/ai_assistant/lib/ai-sdk.ts +5 -0
  169. package/src/modules/ai_assistant/lib/api-discovery-tools.ts +334 -0
  170. package/src/modules/ai_assistant/lib/api-endpoint-index-config.ts +243 -0
  171. package/src/modules/ai_assistant/lib/api-endpoint-index.ts +381 -0
  172. package/src/modules/ai_assistant/lib/auth.ts +185 -0
  173. package/src/modules/ai_assistant/lib/chat-config.ts +152 -0
  174. package/src/modules/ai_assistant/lib/client-factory.ts +130 -0
  175. package/src/modules/ai_assistant/lib/http-server.ts +498 -0
  176. package/src/modules/ai_assistant/lib/in-process-client.ts +205 -0
  177. package/src/modules/ai_assistant/lib/mcp-client.ts +221 -0
  178. package/src/modules/ai_assistant/lib/mcp-dev-server.ts +373 -0
  179. package/src/modules/ai_assistant/lib/mcp-server-config.ts +287 -0
  180. package/src/modules/ai_assistant/lib/mcp-server.ts +214 -0
  181. package/src/modules/ai_assistant/lib/mcp-tool-adapter.ts +76 -0
  182. package/src/modules/ai_assistant/lib/opencode-client.ts +426 -0
  183. package/src/modules/ai_assistant/lib/opencode-handlers.ts +676 -0
  184. package/src/modules/ai_assistant/lib/schema-utils.ts +142 -0
  185. package/src/modules/ai_assistant/lib/tool-executor.ts +71 -0
  186. package/src/modules/ai_assistant/lib/tool-index-config.ts +178 -0
  187. package/src/modules/ai_assistant/lib/tool-loader.ts +149 -0
  188. package/src/modules/ai_assistant/lib/tool-registry.ts +114 -0
  189. package/src/modules/ai_assistant/lib/tool-search.ts +308 -0
  190. package/src/modules/ai_assistant/lib/types.ts +147 -0
  191. package/test-schema.ts +37 -0
  192. package/tsconfig.json +10 -0
  193. package/watch.mjs +6 -0
@@ -0,0 +1,26 @@
1
+ import React from 'react'
2
+
3
+ const aiIcon = React.createElement(
4
+ 'svg',
5
+ { width: 16, height: 16, viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: 2, strokeLinecap: 'round', strokeLinejoin: 'round' },
6
+ React.createElement('path', { d: 'M12 8V4H8' }),
7
+ React.createElement('rect', { width: 16, height: 12, x: 4, y: 8, rx: 2 }),
8
+ React.createElement('path', { d: 'M2 14h2' }),
9
+ React.createElement('path', { d: 'M20 14h2' }),
10
+ React.createElement('path', { d: 'M15 13v2' }),
11
+ React.createElement('path', { d: 'M9 13v2' }),
12
+ )
13
+
14
+ export const metadata = {
15
+ requireAuth: true,
16
+ requireFeatures: ['ai_assistant.view'],
17
+ pageTitle: 'AI Assistant',
18
+ pageTitleKey: 'ai_assistant.config.nav.settings',
19
+ pageGroup: 'Configuration',
20
+ pageGroupKey: 'backend.nav.configuration',
21
+ pageOrder: 430,
22
+ icon: aiIcon,
23
+ breadcrumb: [
24
+ { label: 'AI Assistant', labelKey: 'ai_assistant.config.nav.settings' },
25
+ ],
26
+ } as const
@@ -0,0 +1,12 @@
1
+ import { Page, PageBody } from '@open-mercato/ui/backend/Page'
2
+ import { AiAssistantSettingsPageClient } from '../../../frontend/components/AiAssistantSettingsPageClient'
3
+
4
+ export default async function AiAssistantSettingsPage() {
5
+ return (
6
+ <Page>
7
+ <PageBody>
8
+ <AiAssistantSettingsPageClient />
9
+ </PageBody>
10
+ </Page>
11
+ )
12
+ }
@@ -0,0 +1,233 @@
1
+ import type { ModuleCli } from '@open-mercato/shared/modules/registry'
2
+ import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
3
+ import { fileURLToPath } from 'node:url'
4
+ import { dirname, resolve } from 'node:path'
5
+ import { pathToFileURL } from 'node:url'
6
+
7
+ /**
8
+ * Ensure app bootstrap is called before creating DI container.
9
+ * Uses import.meta.url for runtime path resolution since @/ alias
10
+ * doesn't work with dynamic imports (TypeScript path aliases are
11
+ * compile-time only, not available to Node.js at runtime).
12
+ */
13
+ async function ensureBootstrap(): Promise<void> {
14
+ // First check if DI is already available
15
+ try {
16
+ const { getDiRegistrars } = await import('@open-mercato/shared/lib/di/container')
17
+ getDiRegistrars()
18
+ return // DI already available
19
+ } catch {
20
+ // DI not available, need to bootstrap
21
+ }
22
+
23
+ // Construct absolute path to bootstrap using import.meta.url
24
+ try {
25
+ const __filename = fileURLToPath(import.meta.url)
26
+ const __dirname = dirname(__filename)
27
+ // From packages/ai-assistant/src/modules/ai_assistant/cli.ts
28
+ // to apps/mercato/src/bootstrap.ts:
29
+ // ai_assistant → modules → src → ai-assistant → packages → root (6 levels)
30
+ // then into apps/mercato/src/bootstrap.ts
31
+ const bootstrapPath = resolve(__dirname, '../../../../../../apps/mercato/src/bootstrap.ts')
32
+
33
+ // Dynamic import using file URL
34
+ const bootstrapUrl = pathToFileURL(bootstrapPath).href
35
+ const { bootstrap, isBootstrapped } = await import(bootstrapUrl)
36
+
37
+ if (!isBootstrapped()) {
38
+ bootstrap()
39
+ }
40
+ } catch (error) {
41
+ console.error('[MCP] Bootstrap failed:', error instanceof Error ? error.message : error)
42
+ // Continue - some contexts may not have bootstrap available
43
+ }
44
+ }
45
+
46
+ function parseArgs(rest: string[]): Record<string, string | boolean> {
47
+ const args: Record<string, string | boolean> = {}
48
+ for (let i = 0; i < rest.length; i++) {
49
+ const arg = rest[i]
50
+ if (!arg?.startsWith('--')) continue
51
+
52
+ const [key, value] = arg.replace(/^--/, '').split('=')
53
+ if (value !== undefined) {
54
+ args[key] = value
55
+ } else if (rest[i + 1] && !rest[i + 1]!.startsWith('--')) {
56
+ args[key] = rest[i + 1]!
57
+ i++
58
+ } else {
59
+ args[key] = true
60
+ }
61
+ }
62
+ return args
63
+ }
64
+
65
+ const mcpServe: ModuleCli = {
66
+ command: 'mcp:serve',
67
+ async run(rest) {
68
+ const args = parseArgs(rest)
69
+ const apiKey = String(args['api-key'] ?? args.apiKey ?? '') || null
70
+ const tenantId = String(args.tenant ?? args.tenantId ?? '') || null
71
+ const organizationId = String(args.org ?? args.organizationId ?? '') || null
72
+ const userId = String(args.user ?? args.userId ?? '') || null
73
+ const debug = args.debug === true || args.debug === 'true'
74
+
75
+ // Either API key or tenant is required
76
+ if (!apiKey && !tenantId) {
77
+ console.error('Usage: mercato ai_assistant mcp:serve [options]')
78
+ console.error('')
79
+ console.error('Authentication (choose one):')
80
+ console.error(' --api-key <secret> API key secret for authentication (recommended)')
81
+ console.error(' --tenant <id> Tenant ID (for manual context)')
82
+ console.error('')
83
+ console.error('Options (with --tenant):')
84
+ console.error(' --org <id> Organization ID (optional)')
85
+ console.error(' --user <id> User ID for ACL (optional, uses superadmin if not set)')
86
+ console.error('')
87
+ console.error('Common options:')
88
+ console.error(' --debug Enable debug logging')
89
+ console.error('')
90
+ console.error('Examples:')
91
+ console.error(' mercato ai_assistant mcp:serve --api-key omk_xxxx.yyyy...')
92
+ console.error(' mercato ai_assistant mcp:serve --tenant 123e4567-e89b-12d3-a456-426614174000')
93
+ return
94
+ }
95
+
96
+ await ensureBootstrap()
97
+ const container = await createRequestContainer()
98
+
99
+ const { runMcpServer } = await import('./lib/mcp-server')
100
+
101
+ if (apiKey) {
102
+ await runMcpServer({
103
+ config: {
104
+ name: 'open-mercato-mcp',
105
+ version: '0.1.0',
106
+ debug,
107
+ },
108
+ container,
109
+ apiKeySecret: apiKey,
110
+ })
111
+ } else {
112
+ await runMcpServer({
113
+ config: {
114
+ name: 'open-mercato-mcp',
115
+ version: '0.1.0',
116
+ debug,
117
+ },
118
+ container,
119
+ context: {
120
+ tenantId,
121
+ organizationId,
122
+ userId,
123
+ },
124
+ })
125
+ }
126
+ },
127
+ }
128
+
129
+ const mcpServeHttp: ModuleCli = {
130
+ command: 'mcp:serve-http',
131
+ async run(rest) {
132
+ const args = parseArgs(rest)
133
+ const port = parseInt(String(args.port ?? ''), 10)
134
+ const debug = args.debug === true || args.debug === 'true'
135
+
136
+ if (!port || isNaN(port)) {
137
+ console.error('Usage: mercato ai_assistant mcp:serve-http --port <port> [options]')
138
+ console.error('')
139
+ console.error('Options:')
140
+ console.error(' --port <number> Port to listen on (required)')
141
+ console.error(' --debug Enable debug logging')
142
+ console.error('')
143
+ console.error('Authentication:')
144
+ console.error(' Clients must provide API key via x-api-key header')
145
+ console.error('')
146
+ console.error('Example:')
147
+ console.error(' mercato ai_assistant mcp:serve-http --port 3001')
148
+ return
149
+ }
150
+
151
+ await ensureBootstrap()
152
+ const container = await createRequestContainer()
153
+
154
+ const { runMcpHttpServer } = await import('./lib/http-server')
155
+
156
+ await runMcpHttpServer({
157
+ config: {
158
+ name: 'open-mercato-mcp',
159
+ version: '0.1.0',
160
+ debug,
161
+ },
162
+ container,
163
+ port,
164
+ })
165
+ },
166
+ }
167
+
168
+ const mcpDev: ModuleCli = {
169
+ command: 'mcp:dev',
170
+ async run() {
171
+ await ensureBootstrap()
172
+ const { runMcpDevServer } = await import('./lib/mcp-dev-server')
173
+ await runMcpDevServer()
174
+ },
175
+ }
176
+
177
+ const listTools: ModuleCli = {
178
+ command: 'mcp:list-tools',
179
+ async run(rest) {
180
+ const args = parseArgs(rest)
181
+ const verbose = args.verbose === true || args.verbose === 'true'
182
+
183
+ const { loadAllModuleTools } = await import('./lib/tool-loader')
184
+ await loadAllModuleTools()
185
+
186
+ const { getToolRegistry } = await import('./lib/tool-registry')
187
+ const registry = getToolRegistry()
188
+ const toolNames = registry.listToolNames()
189
+
190
+ if (toolNames.length === 0) {
191
+ console.log('\nNo MCP tools registered.')
192
+ console.log('Tools can be registered by modules using registerMcpTool().\n')
193
+ return
194
+ }
195
+
196
+ console.log(`\nRegistered MCP Tools (${toolNames.length}):\n`)
197
+
198
+ // Group tools by module
199
+ const byModule = new Map<string, string[]>()
200
+ for (const name of toolNames) {
201
+ const [module] = name.split('.')
202
+ const list = byModule.get(module) ?? []
203
+ list.push(name)
204
+ byModule.set(module, list)
205
+ }
206
+
207
+ // Sort modules alphabetically
208
+ const sortedModules = Array.from(byModule.keys()).sort()
209
+
210
+ for (const module of sortedModules) {
211
+ const tools = byModule.get(module)!
212
+ console.log(`${module} (${tools.length} tools):`)
213
+
214
+ for (const name of tools.sort()) {
215
+ const tool = registry.getTool(name)
216
+ if (!tool) continue
217
+
218
+ if (verbose) {
219
+ console.log(` ${name}`)
220
+ console.log(` ${tool.description}`)
221
+ if (tool.requiredFeatures?.length) {
222
+ console.log(` Requires: ${tool.requiredFeatures.join(', ')}`)
223
+ }
224
+ } else {
225
+ console.log(` - ${name}`)
226
+ }
227
+ }
228
+ console.log('')
229
+ }
230
+ },
231
+ }
232
+
233
+ export default [mcpServe, mcpServeHttp, mcpDev, listTools]
@@ -0,0 +1,9 @@
1
+ import { asValue } from 'awilix'
2
+ import type { AwilixContainer } from 'awilix'
3
+ import { toolRegistry } from './lib/tool-registry'
4
+
5
+ export function register(container: AwilixContainer): void {
6
+ container.register({
7
+ mcpToolRegistry: asValue(toolRegistry),
8
+ })
9
+ }