memento-mcp-server 0.1.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 (555) hide show
  1. package/.cursor/rules/cache-management.mdc +171 -0
  2. package/.cursor/rules/database-schema.mdc +344 -0
  3. package/.cursor/rules/deployment.mdc +596 -0
  4. package/.cursor/rules/error-logging.mdc +298 -0
  5. package/.cursor/rules/forgetting-algorithms.mdc +426 -0
  6. package/.cursor/rules/http-server.mdc +432 -0
  7. package/.cursor/rules/hybrid-search.mdc +424 -0
  8. package/.cursor/rules/implementation.mdc +369 -0
  9. package/.cursor/rules/lightweight-embedding.mdc +178 -0
  10. package/.cursor/rules/mcp-client-development.mdc +0 -0
  11. package/.cursor/rules/mcp-server-development.mdc +0 -0
  12. package/.cursor/rules/mcp-tools-architecture.mdc +205 -0
  13. package/.cursor/rules/memento-memory-rule.mdc +8 -0
  14. package/.cursor/rules/memento-project-overview.mdc +0 -0
  15. package/.cursor/rules/memory-algorithms.mdc +502 -0
  16. package/.cursor/rules/monitoring.mdc +622 -0
  17. package/.cursor/rules/performance-alerts.mdc +537 -0
  18. package/.cursor/rules/performance-monitoring.mdc +345 -0
  19. package/.cursor/rules/performance-optimization.mdc +563 -0
  20. package/.cursor/rules/project-structure.mdc +310 -0
  21. package/.cursor/rules/testing.mdc +473 -0
  22. package/.dockerignore +15 -0
  23. package/.eslintrc.json +34 -0
  24. package/.github/ISSUE_TEMPLATE/bug_report.md +51 -0
  25. package/.github/ISSUE_TEMPLATE/feature_request.md +45 -0
  26. package/.github/ISSUE_TEMPLATE/question.md +31 -0
  27. package/.github/PULL_REQUEST_TEMPLATE.md +97 -0
  28. package/AGENTS.md +28 -0
  29. package/CHANGELOG.md +416 -0
  30. package/CODE_OF_CONDUCT.md +62 -0
  31. package/CONTRIBUTING.md +165 -0
  32. package/DOCKER_SETUP_GUIDE.md +84 -0
  33. package/Dockerfile +90 -0
  34. package/INSTALL.en.md +303 -0
  35. package/INSTALL.md +303 -0
  36. package/README.en.md +330 -0
  37. package/README.md +427 -0
  38. package/backup/legacy-removal-20250930-201816/http-server-legacy.ts +1068 -0
  39. package/backup/legacy-removal-20250930-201816/rollback-to-legacy.ps1 +46 -0
  40. package/backup/legacy-removal-20250930-201816/rollback-to-legacy.sh +48 -0
  41. package/dist/algorithms/forgetting-algorithm.d.ts +90 -0
  42. package/dist/algorithms/forgetting-algorithm.d.ts.map +1 -0
  43. package/dist/algorithms/forgetting-algorithm.js +160 -0
  44. package/dist/algorithms/forgetting-algorithm.js.map +1 -0
  45. package/dist/algorithms/hybrid-search-engine.d.ts +108 -0
  46. package/dist/algorithms/hybrid-search-engine.d.ts.map +1 -0
  47. package/dist/algorithms/hybrid-search-engine.js +384 -0
  48. package/dist/algorithms/hybrid-search-engine.js.map +1 -0
  49. package/dist/algorithms/search-engine.d.ts +64 -0
  50. package/dist/algorithms/search-engine.d.ts.map +1 -0
  51. package/dist/algorithms/search-engine.js +304 -0
  52. package/dist/algorithms/search-engine.js.map +1 -0
  53. package/dist/algorithms/search-ranking.d.ts +145 -0
  54. package/dist/algorithms/search-ranking.d.ts.map +1 -0
  55. package/dist/algorithms/search-ranking.js +311 -0
  56. package/dist/algorithms/search-ranking.js.map +1 -0
  57. package/dist/algorithms/spaced-repetition.d.ts +83 -0
  58. package/dist/algorithms/spaced-repetition.d.ts.map +1 -0
  59. package/dist/algorithms/spaced-repetition.js +153 -0
  60. package/dist/algorithms/spaced-repetition.js.map +1 -0
  61. package/dist/algorithms/vector-search-engine.d.ts +96 -0
  62. package/dist/algorithms/vector-search-engine.d.ts.map +1 -0
  63. package/dist/algorithms/vector-search-engine.js +410 -0
  64. package/dist/algorithms/vector-search-engine.js.map +1 -0
  65. package/dist/client/index.d.ts +55 -0
  66. package/dist/client/index.d.ts.map +1 -0
  67. package/dist/client/index.js +179 -0
  68. package/dist/client/index.js.map +1 -0
  69. package/dist/config/index.d.ts +20 -0
  70. package/dist/config/index.d.ts.map +1 -0
  71. package/dist/config/index.js +87 -0
  72. package/dist/config/index.js.map +1 -0
  73. package/dist/database/init.d.ts +7 -0
  74. package/dist/database/init.d.ts.map +1 -0
  75. package/dist/database/init.js +117 -0
  76. package/dist/database/init.js.map +1 -0
  77. package/dist/database/migrate.d.ts +6 -0
  78. package/dist/database/migrate.d.ts.map +1 -0
  79. package/dist/database/migrate.js +84 -0
  80. package/dist/database/migrate.js.map +1 -0
  81. package/dist/database/schema.sql +159 -0
  82. package/dist/npm-client/context-injector.d.ts +106 -0
  83. package/dist/npm-client/context-injector.d.ts.map +1 -0
  84. package/dist/npm-client/context-injector.js +296 -0
  85. package/dist/npm-client/context-injector.js.map +1 -0
  86. package/dist/npm-client/index.d.ts +42 -0
  87. package/dist/npm-client/index.d.ts.map +1 -0
  88. package/dist/npm-client/index.js +43 -0
  89. package/dist/npm-client/index.js.map +1 -0
  90. package/dist/npm-client/memento-client.d.ts +114 -0
  91. package/dist/npm-client/memento-client.d.ts.map +1 -0
  92. package/dist/npm-client/memento-client.js +391 -0
  93. package/dist/npm-client/memento-client.js.map +1 -0
  94. package/dist/npm-client/memory-manager.d.ts +137 -0
  95. package/dist/npm-client/memory-manager.d.ts.map +1 -0
  96. package/dist/npm-client/memory-manager.js +341 -0
  97. package/dist/npm-client/memory-manager.js.map +1 -0
  98. package/dist/npm-client/types.d.ts +216 -0
  99. package/dist/npm-client/types.d.ts.map +1 -0
  100. package/dist/npm-client/types.js +44 -0
  101. package/dist/npm-client/types.js.map +1 -0
  102. package/dist/npm-client/utils.d.ts +91 -0
  103. package/dist/npm-client/utils.d.ts.map +1 -0
  104. package/dist/npm-client/utils.js +351 -0
  105. package/dist/npm-client/utils.js.map +1 -0
  106. package/dist/scripts/copy-assets.d.ts +3 -0
  107. package/dist/scripts/copy-assets.d.ts.map +1 -0
  108. package/dist/scripts/copy-assets.js +31 -0
  109. package/dist/scripts/copy-assets.js.map +1 -0
  110. package/dist/server/http-server.d.ts +28 -0
  111. package/dist/server/http-server.d.ts.map +1 -0
  112. package/dist/server/http-server.js +930 -0
  113. package/dist/server/http-server.js.map +1 -0
  114. package/dist/server/index-backup.d.ts +5 -0
  115. package/dist/server/index-backup.d.ts.map +1 -0
  116. package/dist/server/index-backup.js +793 -0
  117. package/dist/server/index-backup.js.map +1 -0
  118. package/dist/server/index-refactored.d.ts +6 -0
  119. package/dist/server/index-refactored.d.ts.map +1 -0
  120. package/dist/server/index-refactored.js +206 -0
  121. package/dist/server/index-refactored.js.map +1 -0
  122. package/dist/server/index.d.ts +12 -0
  123. package/dist/server/index.d.ts.map +1 -0
  124. package/dist/server/index.js +301 -0
  125. package/dist/server/index.js.map +1 -0
  126. package/dist/server/simple-mcp-server.d.ts +8 -0
  127. package/dist/server/simple-mcp-server.d.ts.map +1 -0
  128. package/dist/server/simple-mcp-server.js +152 -0
  129. package/dist/server/simple-mcp-server.js.map +1 -0
  130. package/dist/services/async-optimizer.d.ts +136 -0
  131. package/dist/services/async-optimizer.d.ts.map +1 -0
  132. package/dist/services/async-optimizer.js +406 -0
  133. package/dist/services/async-optimizer.js.map +1 -0
  134. package/dist/services/batch-scheduler.d.ts +156 -0
  135. package/dist/services/batch-scheduler.d.ts.map +1 -0
  136. package/dist/services/batch-scheduler.js +612 -0
  137. package/dist/services/batch-scheduler.js.map +1 -0
  138. package/dist/services/cache-service.d.ts +168 -0
  139. package/dist/services/cache-service.d.ts.map +1 -0
  140. package/dist/services/cache-service.js +360 -0
  141. package/dist/services/cache-service.js.map +1 -0
  142. package/dist/services/database-optimizer.d.ts +110 -0
  143. package/dist/services/database-optimizer.d.ts.map +1 -0
  144. package/dist/services/database-optimizer.js +369 -0
  145. package/dist/services/database-optimizer.js.map +1 -0
  146. package/dist/services/embedding-provider-factory.d.ts +62 -0
  147. package/dist/services/embedding-provider-factory.d.ts.map +1 -0
  148. package/dist/services/embedding-provider-factory.js +152 -0
  149. package/dist/services/embedding-provider-factory.js.map +1 -0
  150. package/dist/services/embedding-service.d.ts +95 -0
  151. package/dist/services/embedding-service.d.ts.map +1 -0
  152. package/dist/services/embedding-service.js +276 -0
  153. package/dist/services/embedding-service.js.map +1 -0
  154. package/dist/services/error-logging-service.d.ts +134 -0
  155. package/dist/services/error-logging-service.d.ts.map +1 -0
  156. package/dist/services/error-logging-service.js +271 -0
  157. package/dist/services/error-logging-service.js.map +1 -0
  158. package/dist/services/forgetting-policy-service.d.ts +94 -0
  159. package/dist/services/forgetting-policy-service.d.ts.map +1 -0
  160. package/dist/services/forgetting-policy-service.js +233 -0
  161. package/dist/services/forgetting-policy-service.js.map +1 -0
  162. package/dist/services/gemini-embedding-service.d.ts +82 -0
  163. package/dist/services/gemini-embedding-service.d.ts.map +1 -0
  164. package/dist/services/gemini-embedding-service.js +232 -0
  165. package/dist/services/gemini-embedding-service.js.map +1 -0
  166. package/dist/services/lightweight-embedding-service.d.ts +95 -0
  167. package/dist/services/lightweight-embedding-service.d.ts.map +1 -0
  168. package/dist/services/lightweight-embedding-service.js +263 -0
  169. package/dist/services/lightweight-embedding-service.js.map +1 -0
  170. package/dist/services/memory-embedding-service.d.ts +69 -0
  171. package/dist/services/memory-embedding-service.d.ts.map +1 -0
  172. package/dist/services/memory-embedding-service.js +223 -0
  173. package/dist/services/memory-embedding-service.js.map +1 -0
  174. package/dist/services/minilm-embedding-service.d.ts +92 -0
  175. package/dist/services/minilm-embedding-service.d.ts.map +1 -0
  176. package/dist/services/minilm-embedding-service.js +216 -0
  177. package/dist/services/minilm-embedding-service.js.map +1 -0
  178. package/dist/services/performance-alert-service.d.ts +142 -0
  179. package/dist/services/performance-alert-service.d.ts.map +1 -0
  180. package/dist/services/performance-alert-service.js +366 -0
  181. package/dist/services/performance-alert-service.js.map +1 -0
  182. package/dist/services/performance-monitor.d.ts +144 -0
  183. package/dist/services/performance-monitor.d.ts.map +1 -0
  184. package/dist/services/performance-monitor.js +416 -0
  185. package/dist/services/performance-monitor.js.map +1 -0
  186. package/dist/services/performance-monitoring-integration.d.ts +77 -0
  187. package/dist/services/performance-monitoring-integration.d.ts.map +1 -0
  188. package/dist/services/performance-monitoring-integration.js +177 -0
  189. package/dist/services/performance-monitoring-integration.js.map +1 -0
  190. package/dist/services/unified-embedding-service.d.ts +75 -0
  191. package/dist/services/unified-embedding-service.d.ts.map +1 -0
  192. package/dist/services/unified-embedding-service.js +211 -0
  193. package/dist/services/unified-embedding-service.js.map +1 -0
  194. package/dist/test/debug-http-v2.d.ts +5 -0
  195. package/dist/test/debug-http-v2.d.ts.map +1 -0
  196. package/dist/test/debug-http-v2.js +28 -0
  197. package/dist/test/debug-http-v2.js.map +1 -0
  198. package/dist/test/performance-benchmark.d.ts +57 -0
  199. package/dist/test/performance-benchmark.d.ts.map +1 -0
  200. package/dist/test/performance-benchmark.js +427 -0
  201. package/dist/test/performance-benchmark.js.map +1 -0
  202. package/dist/test/test-alerts-direct.d.ts +7 -0
  203. package/dist/test/test-alerts-direct.d.ts.map +1 -0
  204. package/dist/test/test-alerts-direct.js +101 -0
  205. package/dist/test/test-alerts-direct.js.map +1 -0
  206. package/dist/test/test-batch-scheduler.d.ts +2 -0
  207. package/dist/test/test-batch-scheduler.d.ts.map +1 -0
  208. package/dist/test/test-batch-scheduler.js +156 -0
  209. package/dist/test/test-batch-scheduler.js.map +1 -0
  210. package/dist/test/test-client.d.ts +5 -0
  211. package/dist/test/test-client.d.ts.map +1 -0
  212. package/dist/test/test-client.js +86 -0
  213. package/dist/test/test-client.js.map +1 -0
  214. package/dist/test/test-embedding.d.ts +6 -0
  215. package/dist/test/test-embedding.d.ts.map +1 -0
  216. package/dist/test/test-embedding.js +142 -0
  217. package/dist/test/test-embedding.js.map +1 -0
  218. package/dist/test/test-error-logging.d.ts +7 -0
  219. package/dist/test/test-error-logging.d.ts.map +1 -0
  220. package/dist/test/test-error-logging.js +105 -0
  221. package/dist/test/test-error-logging.js.map +1 -0
  222. package/dist/test/test-forgetting.d.ts +6 -0
  223. package/dist/test/test-forgetting.d.ts.map +1 -0
  224. package/dist/test/test-forgetting.js +154 -0
  225. package/dist/test/test-forgetting.js.map +1 -0
  226. package/dist/test/test-gemini-embedding.d.ts +7 -0
  227. package/dist/test/test-gemini-embedding.d.ts.map +1 -0
  228. package/dist/test/test-gemini-embedding.js +134 -0
  229. package/dist/test/test-gemini-embedding.js.map +1 -0
  230. package/dist/test/test-http-server-v2-simple.d.ts +6 -0
  231. package/dist/test/test-http-server-v2-simple.d.ts.map +1 -0
  232. package/dist/test/test-http-server-v2-simple.js +131 -0
  233. package/dist/test/test-http-server-v2-simple.js.map +1 -0
  234. package/dist/test/test-http-server-v2.d.ts +7 -0
  235. package/dist/test/test-http-server-v2.d.ts.map +1 -0
  236. package/dist/test/test-http-server-v2.js +529 -0
  237. package/dist/test/test-http-server-v2.js.map +1 -0
  238. package/dist/test/test-lightweight-embedding.d.ts +6 -0
  239. package/dist/test/test-lightweight-embedding.d.ts.map +1 -0
  240. package/dist/test/test-lightweight-embedding.js +189 -0
  241. package/dist/test/test-lightweight-embedding.js.map +1 -0
  242. package/dist/test/test-m1-completion.d.ts +7 -0
  243. package/dist/test/test-m1-completion.d.ts.map +1 -0
  244. package/dist/test/test-m1-completion.js +124 -0
  245. package/dist/test/test-m1-completion.js.map +1 -0
  246. package/dist/test/test-memory-injection-prompt.d.ts +2 -0
  247. package/dist/test/test-memory-injection-prompt.d.ts.map +1 -0
  248. package/dist/test/test-memory-injection-prompt.js +299 -0
  249. package/dist/test/test-memory-injection-prompt.js.map +1 -0
  250. package/dist/test/test-performance-alerts.d.ts +7 -0
  251. package/dist/test/test-performance-alerts.d.ts.map +1 -0
  252. package/dist/test/test-performance-alerts.js +109 -0
  253. package/dist/test/test-performance-alerts.js.map +1 -0
  254. package/dist/test/test-performance-monitor.d.ts +2 -0
  255. package/dist/test/test-performance-monitor.d.ts.map +1 -0
  256. package/dist/test/test-performance-monitor.js +182 -0
  257. package/dist/test/test-performance-monitor.js.map +1 -0
  258. package/dist/test/test-performance-monitoring.d.ts +6 -0
  259. package/dist/test/test-performance-monitoring.d.ts.map +1 -0
  260. package/dist/test/test-performance-monitoring.js +156 -0
  261. package/dist/test/test-performance-monitoring.js.map +1 -0
  262. package/dist/test/test-search.d.ts +5 -0
  263. package/dist/test/test-search.d.ts.map +1 -0
  264. package/dist/test/test-search.js +141 -0
  265. package/dist/test/test-search.js.map +1 -0
  266. package/dist/test/test-simple-alerts.d.ts +6 -0
  267. package/dist/test/test-simple-alerts.d.ts.map +1 -0
  268. package/dist/test/test-simple-alerts.js +106 -0
  269. package/dist/test/test-simple-alerts.js.map +1 -0
  270. package/dist/test/test-vector-search-engine.d.ts +2 -0
  271. package/dist/test/test-vector-search-engine.d.ts.map +1 -0
  272. package/dist/test/test-vector-search-engine.js +225 -0
  273. package/dist/test/test-vector-search-engine.js.map +1 -0
  274. package/dist/tools/base-tool.d.ts +64 -0
  275. package/dist/tools/base-tool.d.ts.map +1 -0
  276. package/dist/tools/base-tool.js +158 -0
  277. package/dist/tools/base-tool.js.map +1 -0
  278. package/dist/tools/cleanup-memory-tool.d.ts +10 -0
  279. package/dist/tools/cleanup-memory-tool.d.ts.map +1 -0
  280. package/dist/tools/cleanup-memory-tool.js +66 -0
  281. package/dist/tools/cleanup-memory-tool.js.map +1 -0
  282. package/dist/tools/database-optimize-tool.d.ts +10 -0
  283. package/dist/tools/database-optimize-tool.d.ts.map +1 -0
  284. package/dist/tools/database-optimize-tool.js +64 -0
  285. package/dist/tools/database-optimize-tool.js.map +1 -0
  286. package/dist/tools/error-stats.d.ts +93 -0
  287. package/dist/tools/error-stats.d.ts.map +1 -0
  288. package/dist/tools/error-stats.js +115 -0
  289. package/dist/tools/error-stats.js.map +1 -0
  290. package/dist/tools/forget-tool.d.ts +63 -0
  291. package/dist/tools/forget-tool.d.ts.map +1 -0
  292. package/dist/tools/forget-tool.js +340 -0
  293. package/dist/tools/forget-tool.js.map +1 -0
  294. package/dist/tools/forgetting-stats-tool.d.ts +10 -0
  295. package/dist/tools/forgetting-stats-tool.d.ts.map +1 -0
  296. package/dist/tools/forgetting-stats-tool.js +37 -0
  297. package/dist/tools/forgetting-stats-tool.js.map +1 -0
  298. package/dist/tools/index.d.ts +33 -0
  299. package/dist/tools/index.d.ts.map +1 -0
  300. package/dist/tools/index.js +55 -0
  301. package/dist/tools/index.js.map +1 -0
  302. package/dist/tools/memory-injection-prompt.d.ts +31 -0
  303. package/dist/tools/memory-injection-prompt.d.ts.map +1 -0
  304. package/dist/tools/memory-injection-prompt.js +203 -0
  305. package/dist/tools/memory-injection-prompt.js.map +1 -0
  306. package/dist/tools/performance-alerts.d.ts +127 -0
  307. package/dist/tools/performance-alerts.d.ts.map +1 -0
  308. package/dist/tools/performance-alerts.js +208 -0
  309. package/dist/tools/performance-alerts.js.map +1 -0
  310. package/dist/tools/performance-stats-tool.d.ts +10 -0
  311. package/dist/tools/performance-stats-tool.d.ts.map +1 -0
  312. package/dist/tools/performance-stats-tool.js +38 -0
  313. package/dist/tools/performance-stats-tool.js.map +1 -0
  314. package/dist/tools/pin-tool.d.ts +39 -0
  315. package/dist/tools/pin-tool.d.ts.map +1 -0
  316. package/dist/tools/pin-tool.js +211 -0
  317. package/dist/tools/pin-tool.js.map +1 -0
  318. package/dist/tools/recall-tool.d.ts +27 -0
  319. package/dist/tools/recall-tool.d.ts.map +1 -0
  320. package/dist/tools/recall-tool.js +335 -0
  321. package/dist/tools/recall-tool.js.map +1 -0
  322. package/dist/tools/remember-tool.d.ts +10 -0
  323. package/dist/tools/remember-tool.d.ts.map +1 -0
  324. package/dist/tools/remember-tool.js +101 -0
  325. package/dist/tools/remember-tool.js.map +1 -0
  326. package/dist/tools/resolve-error.d.ts +54 -0
  327. package/dist/tools/resolve-error.d.ts.map +1 -0
  328. package/dist/tools/resolve-error.js +63 -0
  329. package/dist/tools/resolve-error.js.map +1 -0
  330. package/dist/tools/tool-registry.d.ts +134 -0
  331. package/dist/tools/tool-registry.d.ts.map +1 -0
  332. package/dist/tools/tool-registry.js +337 -0
  333. package/dist/tools/tool-registry.js.map +1 -0
  334. package/dist/tools/types.d.ts +56 -0
  335. package/dist/tools/types.d.ts.map +1 -0
  336. package/dist/tools/types.js +23 -0
  337. package/dist/tools/types.js.map +1 -0
  338. package/dist/tools/unpin-tool.d.ts +43 -0
  339. package/dist/tools/unpin-tool.d.ts.map +1 -0
  340. package/dist/tools/unpin-tool.js +233 -0
  341. package/dist/tools/unpin-tool.js.map +1 -0
  342. package/dist/types/embedding.types.d.ts +65 -0
  343. package/dist/types/embedding.types.d.ts.map +1 -0
  344. package/dist/types/embedding.types.js +6 -0
  345. package/dist/types/embedding.types.js.map +1 -0
  346. package/dist/types/index.d.ts +103 -0
  347. package/dist/types/index.d.ts.map +1 -0
  348. package/dist/types/index.js +5 -0
  349. package/dist/types/index.js.map +1 -0
  350. package/dist/utils/database.d.ts +62 -0
  351. package/dist/utils/database.d.ts.map +1 -0
  352. package/dist/utils/database.js +399 -0
  353. package/dist/utils/database.js.map +1 -0
  354. package/dist/utils/stopwords.d.ts +18 -0
  355. package/dist/utils/stopwords.d.ts.map +1 -0
  356. package/dist/utils/stopwords.js +117 -0
  357. package/dist/utils/stopwords.js.map +1 -0
  358. package/docker-compose.dev.yml +50 -0
  359. package/docker-compose.prod.yml +77 -0
  360. package/docker-compose.yml +43 -0
  361. package/docs/en/Memento-Goals.md +217 -0
  362. package/docs/en/Memento-M1-DetailSpecs.md +130 -0
  363. package/docs/en/Memento-Milestones.md +135 -0
  364. package/docs/en/Search-Ranking-Memory-Decay-Formulas.md +177 -0
  365. package/docs/en/api-reference.md +658 -0
  366. package/docs/en/architecture.md +1302 -0
  367. package/docs/en/developer-guide.md +1005 -0
  368. package/docs/en/user-manual.md +595 -0
  369. package/docs/ko/Memento-Goals.md +217 -0
  370. package/docs/ko/Memento-M1-DetailSpecs.md +130 -0
  371. package/docs/ko/Memento-Milestones.md +134 -0
  372. package/docs/ko/Search-Ranking-Memory-Decay-Formulas.md +177 -0
  373. package/docs/ko/api-reference.md +658 -0
  374. package/docs/ko/architecture.md +1302 -0
  375. package/docs/ko/developer-guide.md +1006 -0
  376. package/docs/ko/embedding-api-reference.md +122 -0
  377. package/docs/ko/embedding-configuration.md +62 -0
  378. package/docs/ko/embedding-performance-benchmark.md +62 -0
  379. package/docs/ko/embedding-service-guide.md +314 -0
  380. package/docs/ko/user-manual.md +595 -0
  381. package/env.example +49 -0
  382. package/install.sh +191 -0
  383. package/mcp-http-client.js +218 -0
  384. package/mcp.json +0 -0
  385. package/package.json +125 -0
  386. package/packages/mcp-client/docs/API-REFERENCE.md +560 -0
  387. package/packages/mcp-client/docs/BEST-PRACTICES.md +564 -0
  388. package/packages/mcp-client/docs/MIGRATION-GUIDE.md +344 -0
  389. package/packages/mcp-client/docs/PERFORMANCE-GUIDE.md +476 -0
  390. package/packages/mcp-client/docs/TROUBLESHOOTING.md +564 -0
  391. package/packages/mcp-client/package-lock.json +907 -0
  392. package/packages/mcp-client/package.json +58 -0
  393. package/packages/mcp-client/performance-optimizer.js +428 -0
  394. package/packages/mcp-client/test-basic.js +65 -0
  395. package/packages/mcp-client/test-integration.js +366 -0
  396. package/scripts/auto-setup.js +234 -0
  397. package/scripts/backup-daily.bat +28 -0
  398. package/scripts/backup-embeddings.js +108 -0
  399. package/scripts/check-db-integrity.js +93 -0
  400. package/scripts/debug-embeddings.js +184 -0
  401. package/scripts/direct-sql-migration.sql +36 -0
  402. package/scripts/docker-migration.sh +105 -0
  403. package/scripts/fix-migration.js +93 -0
  404. package/scripts/fix-vector-dimensions.js +206 -0
  405. package/scripts/migrate-embedding-data.js +307 -0
  406. package/scripts/regenerate-embeddings.js +144 -0
  407. package/scripts/restore-legacy.ps1 +60 -0
  408. package/scripts/restore-legacy.sh +62 -0
  409. package/scripts/run-migration.js +122 -0
  410. package/scripts/safe-migration.js +150 -0
  411. package/scripts/simple-migrate.js +41 -0
  412. package/scripts/simple-update.js +123 -0
  413. package/scripts/start-container.sh +10 -0
  414. package/src/algorithms/forgetting-algorithm.spec.ts +538 -0
  415. package/src/algorithms/forgetting-algorithm.ts +243 -0
  416. package/src/algorithms/hybrid-search-engine.spec.ts +484 -0
  417. package/src/algorithms/hybrid-search-engine.ts +489 -0
  418. package/src/algorithms/search-engine.spec.ts +429 -0
  419. package/src/algorithms/search-engine.ts +392 -0
  420. package/src/algorithms/search-ranking.spec.ts +293 -0
  421. package/src/algorithms/search-ranking.ts +407 -0
  422. package/src/algorithms/spaced-repetition.spec.ts +510 -0
  423. package/src/algorithms/spaced-repetition.ts +238 -0
  424. package/src/algorithms/vector-search-engine.ts +505 -0
  425. package/src/client/index.spec.ts +427 -0
  426. package/src/client/index.ts +222 -0
  427. package/src/config/index.spec.ts +339 -0
  428. package/src/config/index.ts +106 -0
  429. package/src/database/init.spec.ts +239 -0
  430. package/src/database/init.ts +130 -0
  431. package/src/database/migrate.spec.ts +293 -0
  432. package/src/database/migrate.ts +94 -0
  433. package/src/database/migrations/001_add_embedding_metadata.sql +29 -0
  434. package/src/database/schema.sql +159 -0
  435. package/src/npm-client/context-injector.spec.ts +335 -0
  436. package/src/npm-client/context-injector.ts +412 -0
  437. package/src/npm-client/index.spec.ts +108 -0
  438. package/src/npm-client/index.ts +96 -0
  439. package/src/npm-client/memento-client.spec.ts +549 -0
  440. package/src/npm-client/memento-client.ts +501 -0
  441. package/src/npm-client/memory-manager.spec.ts +374 -0
  442. package/src/npm-client/memory-manager.ts +414 -0
  443. package/src/npm-client/types.spec.ts +427 -0
  444. package/src/npm-client/types.ts +296 -0
  445. package/src/npm-client/utils.spec.ts +355 -0
  446. package/src/npm-client/utils.ts +423 -0
  447. package/src/scripts/copy-assets.js +37 -0
  448. package/src/server/http-server.spec.ts +648 -0
  449. package/src/server/http-server.ts +1030 -0
  450. package/src/server/index-backup.ts +875 -0
  451. package/src/server/index-refactored.ts +237 -0
  452. package/src/server/index.spec.ts +281 -0
  453. package/src/server/index.ts +347 -0
  454. package/src/server/simple-mcp-server.spec.ts +207 -0
  455. package/src/server/simple-mcp-server.ts +173 -0
  456. package/src/services/async-optimizer.spec.ts +569 -0
  457. package/src/services/async-optimizer.ts +484 -0
  458. package/src/services/batch-scheduler.ts +759 -0
  459. package/src/services/cache-service.spec.ts +372 -0
  460. package/src/services/cache-service.ts +434 -0
  461. package/src/services/database-optimizer.spec.ts +344 -0
  462. package/src/services/database-optimizer.ts +450 -0
  463. package/src/services/embedding-provider-factory.ts +173 -0
  464. package/src/services/embedding-service.spec.ts +342 -0
  465. package/src/services/embedding-service.ts +333 -0
  466. package/src/services/error-logging-service.spec.ts +416 -0
  467. package/src/services/error-logging-service.ts +383 -0
  468. package/src/services/forgetting-policy-service.spec.ts +140 -0
  469. package/src/services/forgetting-policy-service.ts +334 -0
  470. package/src/services/gemini-embedding-service.spec.ts +463 -0
  471. package/src/services/gemini-embedding-service.ts +283 -0
  472. package/src/services/lightweight-embedding-service.spec.ts +458 -0
  473. package/src/services/lightweight-embedding-service.ts +324 -0
  474. package/src/services/memory-embedding-service.spec.ts +417 -0
  475. package/src/services/memory-embedding-service.ts +289 -0
  476. package/src/services/minilm-embedding-service.spec.ts +104 -0
  477. package/src/services/minilm-embedding-service.ts +262 -0
  478. package/src/services/performance-alert-service.spec.ts +517 -0
  479. package/src/services/performance-alert-service.ts +477 -0
  480. package/src/services/performance-monitor.spec.ts +401 -0
  481. package/src/services/performance-monitor.ts +532 -0
  482. package/src/services/performance-monitoring-integration.spec.ts +478 -0
  483. package/src/services/performance-monitoring-integration.ts.bak +276 -0
  484. package/src/services/unified-embedding-service.spec.ts +224 -0
  485. package/src/services/unified-embedding-service.ts +255 -0
  486. package/src/test/debug-http-v2.ts +30 -0
  487. package/src/test/embedding-integration-test.spec.ts +295 -0
  488. package/src/test/embedding-integration-test.ts +295 -0
  489. package/src/test/embedding-performance-benchmark.spec.ts +354 -0
  490. package/src/test/embedding-performance-benchmark.ts +312 -0
  491. package/src/test/performance-benchmark.ts +565 -0
  492. package/src/test/test-alerts-direct.ts +136 -0
  493. package/src/test/test-batch-scheduler-simple.spec.ts +122 -0
  494. package/src/test/test-batch-scheduler.spec.ts +453 -0
  495. package/src/test/test-batch-scheduler.ts +182 -0
  496. package/src/test/test-client.ts +97 -0
  497. package/src/test/test-embedding.ts +153 -0
  498. package/src/test/test-error-handling.spec.ts +575 -0
  499. package/src/test/test-error-logging.ts +117 -0
  500. package/src/test/test-forgetting.ts +162 -0
  501. package/src/test/test-gemini-embedding.ts +159 -0
  502. package/src/test/test-http-server-v2-simple.ts +147 -0
  503. package/src/test/test-http-server-v2.ts +586 -0
  504. package/src/test/test-hybrid-search-engine.spec.ts +521 -0
  505. package/src/test/test-integration-fixed.spec.ts +612 -0
  506. package/src/test/test-integration.spec.ts +463 -0
  507. package/src/test/test-lightweight-embedding.ts +208 -0
  508. package/src/test/test-m1-completion.spec.ts +614 -0
  509. package/src/test/test-m1-completion.ts +141 -0
  510. package/src/test/test-m1-integration.spec.ts +514 -0
  511. package/src/test/test-memory-injection-prompt.spec.ts +650 -0
  512. package/src/test/test-memory-injection-prompt.ts +391 -0
  513. package/src/test/test-performance-alerts.ts +125 -0
  514. package/src/test/test-performance-monitor-updates.spec.ts +490 -0
  515. package/src/test/test-performance-monitor.spec.ts +284 -0
  516. package/src/test/test-performance-monitor.ts +228 -0
  517. package/src/test/test-performance-monitoring.ts +171 -0
  518. package/src/test/test-search.ts +151 -0
  519. package/src/test/test-simple-alerts.ts +136 -0
  520. package/src/test/test-vector-search-engine.spec.ts +408 -0
  521. package/src/test/test-vector-search-engine.ts +303 -0
  522. package/src/tools/base-tool.ts +189 -0
  523. package/src/tools/cleanup-memory-tool.ts +77 -0
  524. package/src/tools/database-optimize-tool.ts +79 -0
  525. package/src/tools/error-stats.ts +119 -0
  526. package/src/tools/forget-tool.spec.ts +613 -0
  527. package/src/tools/forget-tool.ts +454 -0
  528. package/src/tools/forgetting-stats-tool.ts +47 -0
  529. package/src/tools/index.ts +71 -0
  530. package/src/tools/memory-injection-prompt.ts +257 -0
  531. package/src/tools/performance-alerts.ts +226 -0
  532. package/src/tools/performance-stats-tool.ts +48 -0
  533. package/src/tools/pin-tool.spec.ts +497 -0
  534. package/src/tools/pin-tool.ts +277 -0
  535. package/src/tools/recall-tool.spec.ts +475 -0
  536. package/src/tools/recall-tool.ts +389 -0
  537. package/src/tools/remember-tool.spec.ts +469 -0
  538. package/src/tools/remember-tool.ts +112 -0
  539. package/src/tools/resolve-error.ts +69 -0
  540. package/src/tools/tool-registry.ts +417 -0
  541. package/src/tools/types.ts +63 -0
  542. package/src/tools/unpin-tool.spec.ts +549 -0
  543. package/src/tools/unpin-tool.ts +306 -0
  544. package/src/types/embedding.types.ts +78 -0
  545. package/src/types/index.spec.ts +420 -0
  546. package/src/types/index.ts +117 -0
  547. package/src/utils/database.spec.ts +77 -0
  548. package/src/utils/database.ts +458 -0
  549. package/src/utils/stopwords.ts +128 -0
  550. package/start-docker-setup.bat +38 -0
  551. package/static/logo.png +0 -0
  552. package/static/memento_logo.svg +2 -0
  553. package/test-docker.js +103 -0
  554. package/tsconfig.json +46 -0
  555. package/vitest.config.ts +23 -0
@@ -0,0 +1,930 @@
1
+ /**
2
+ * HTTP/WebSocket 기반 MCP μ„œλ²„ v2
3
+ * λͺ¨λ“ˆν™”λœ ꡬ쑰둜 μƒˆλ‘œ κ΅¬ν˜„
4
+ */
5
+ import express from 'express';
6
+ import { WebSocketServer } from 'ws';
7
+ import cors from 'cors';
8
+ import { createServer } from 'http';
9
+ import { initializeDatabase, closeDatabase } from '../database/init.js';
10
+ import { mementoConfig, validateConfig } from '../config/index.js';
11
+ import { SearchEngine } from '../algorithms/search-engine.js';
12
+ import { HybridSearchEngine } from '../algorithms/hybrid-search-engine.js';
13
+ import { getVectorSearchEngine } from '../algorithms/vector-search-engine.js';
14
+ import { MemoryEmbeddingService } from '../services/memory-embedding-service.js';
15
+ import { getBatchScheduler } from '../services/batch-scheduler.js';
16
+ import { getPerformanceMonitor } from '../services/performance-monitor.js';
17
+ import { getToolRegistry } from '../tools/index.js';
18
+ import Database from 'better-sqlite3';
19
+ // μ „μ—­ λ³€μˆ˜
20
+ let db = null;
21
+ let searchEngine;
22
+ let hybridSearchEngine;
23
+ let vectorSearchEngine;
24
+ let embeddingService;
25
+ function setTestDependencies({ database, searchEngine: search, hybridSearchEngine: hybrid, embeddingService: embedding }) {
26
+ db = database;
27
+ searchEngine = search ?? new SearchEngine();
28
+ hybridSearchEngine = hybrid ?? new HybridSearchEngine();
29
+ embeddingService = embedding ?? new MemoryEmbeddingService();
30
+ }
31
+ // Express μ•± 생성
32
+ const app = express();
33
+ const server = createServer(app);
34
+ // 미듀웨어 μ„€μ •
35
+ app.use(cors({
36
+ origin: '*',
37
+ methods: ['GET', 'POST', 'OPTIONS'],
38
+ allowedHeaders: ['Content-Type', 'Authorization', 'Cache-Control']
39
+ }));
40
+ app.use(express.json({ limit: '10mb' }));
41
+ app.use(express.urlencoded({ extended: true }));
42
+ // κΈ°λ³Έ API μ—”λ“œν¬μΈνŠΈ
43
+ app.get('/health', (req, res) => {
44
+ res.json({
45
+ status: 'healthy',
46
+ server: mementoConfig.serverName,
47
+ version: mementoConfig.serverVersion,
48
+ database: db ? 'connected' : 'disconnected',
49
+ timestamp: new Date().toISOString()
50
+ });
51
+ });
52
+ app.get('/tools', (req, res) => {
53
+ try {
54
+ const toolRegistry = getToolRegistry();
55
+ const tools = toolRegistry.getAll();
56
+ res.json({
57
+ tools,
58
+ count: tools.length,
59
+ server: mementoConfig.serverName
60
+ });
61
+ }
62
+ catch (error) {
63
+ console.error('❌ 도ꡬ λͺ©λ‘ 쑰회 μ‹€νŒ¨:', error);
64
+ res.status(500).json({
65
+ error: 'Failed to get tools',
66
+ message: error instanceof Error ? error.message : 'Unknown error'
67
+ });
68
+ }
69
+ });
70
+ // 도ꡬ μ‹€ν–‰ μ—”λ“œν¬μΈνŠΈ
71
+ app.post('/tools/:name', async (req, res) => {
72
+ const { name } = req.params;
73
+ const params = req.body;
74
+ try {
75
+ const toolRegistry = getToolRegistry();
76
+ // 도ꡬ μ»¨ν…μŠ€νŠΈ 생성
77
+ const context = {
78
+ db,
79
+ services: {
80
+ searchEngine,
81
+ hybridSearchEngine,
82
+ embeddingService
83
+ }
84
+ };
85
+ // 도ꡬ μ‹€ν–‰
86
+ const result = await toolRegistry.execute(name, params, context);
87
+ return res.json({
88
+ result,
89
+ tool: name,
90
+ timestamp: new Date().toISOString()
91
+ });
92
+ }
93
+ catch (error) {
94
+ console.error(`❌ Tool ${name} μ‹€ν–‰ μ‹€νŒ¨:`, error);
95
+ return res.status(500).json({
96
+ error: 'Tool execution failed',
97
+ tool: name,
98
+ message: error instanceof Error ? error.message : 'Unknown error'
99
+ });
100
+ }
101
+ });
102
+ // MCP SSE μ—”λ“œν¬μΈνŠΈ - MCP SDK ν˜Έν™˜ κ΅¬ν˜„
103
+ // Store transports by session ID
104
+ const transports = {};
105
+ // SSE endpoint for establishing the stream
106
+ app.get('/mcp', async (req, res) => {
107
+ console.log('πŸ”— MCP SSE ν΄λΌμ΄μ–ΈνŠΈ μ—°κ²° μš”μ²­');
108
+ try {
109
+ // SSE 헀더 μ„€μ •
110
+ res.writeHead(200, {
111
+ 'Content-Type': 'text/event-stream',
112
+ 'Cache-Control': 'no-cache, no-transform',
113
+ 'Connection': 'keep-alive',
114
+ 'Access-Control-Allow-Origin': '*',
115
+ 'Access-Control-Allow-Headers': 'Cache-Control, Content-Type, Authorization',
116
+ 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
117
+ 'X-Accel-Buffering': 'no' // nginx 버퍼링 λΉ„ν™œμ„±ν™”
118
+ });
119
+ // Generate session ID
120
+ const sessionId = `session_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
121
+ // Send the endpoint event with session ID
122
+ const endpointUrl = `/messages?sessionId=${sessionId}`;
123
+ res.write(`event: endpoint\ndata: ${endpointUrl}\n\n`);
124
+ // MCP μ„œλ²„ μ€€λΉ„ μ™„λ£Œ μ•Œλ¦Ό (ν΄λΌμ΄μ–ΈνŠΈκ°€ initializeλ₯Ό 보내야 함)
125
+ res.write(`data: {"type": "ready"}\n\n`);
126
+ // Keep-alive ping 전솑
127
+ const keepAliveInterval = setInterval(() => {
128
+ if (res.writableEnded) {
129
+ clearInterval(keepAliveInterval);
130
+ return;
131
+ }
132
+ try {
133
+ res.write(`data: {"type": "ping"}\n\n`);
134
+ }
135
+ catch (error) {
136
+ clearInterval(keepAliveInterval);
137
+ }
138
+ }, 30000); // 30μ΄ˆλ§ˆλ‹€ ping
139
+ // Store the transport info
140
+ transports[sessionId] = {
141
+ res: res,
142
+ sessionId: sessionId,
143
+ keepAliveInterval: keepAliveInterval
144
+ };
145
+ // μ—°κ²° μ’…λ£Œ 처리
146
+ req.on('close', () => {
147
+ console.log(`πŸ”Œ MCP SSE ν΄λΌμ΄μ–ΈνŠΈ μ—°κ²° 정상 μ’…λ£Œλ¨ (session: ${sessionId})`);
148
+ clearInterval(keepAliveInterval);
149
+ delete transports[sessionId];
150
+ });
151
+ req.on('error', (error) => {
152
+ // ECONNRESET은 정상적인 μ—°κ²° μ’…λ£Œμ΄λ―€λ‘œ μ—λŸ¬λ‘œ μ²˜λ¦¬ν•˜μ§€ μ•ŠμŒ
153
+ if (error.code === 'ECONNRESET') {
154
+ console.log(`πŸ”Œ MCP SSE ν΄λΌμ΄μ–ΈνŠΈ μ—°κ²° 정상 μ’…λ£Œλ¨ (session: ${sessionId})`);
155
+ }
156
+ else {
157
+ console.error(`❌ MCP SSE μ—°κ²° μ—λŸ¬ (session: ${sessionId}):`, error);
158
+ }
159
+ clearInterval(keepAliveInterval);
160
+ delete transports[sessionId];
161
+ });
162
+ console.log(`βœ… MCP SSE 슀트림 μ„€μ • μ™„λ£Œ (session: ${sessionId})`);
163
+ return;
164
+ }
165
+ catch (error) {
166
+ console.error('❌ SSE 슀트림 μ„€μ • μ‹€νŒ¨:', error);
167
+ if (!res.headersSent) {
168
+ res.status(500).send('Error establishing SSE stream');
169
+ }
170
+ return;
171
+ }
172
+ });
173
+ // Messages endpoint for receiving client JSON-RPC requests
174
+ app.post('/messages', express.json(), async (req, res) => {
175
+ console.log('πŸ“¨ MCP λ©”μ‹œμ§€ μˆ˜μ‹ :', req.body.method);
176
+ // Extract session ID from URL query parameter
177
+ const sessionId = req.query.sessionId;
178
+ if (!sessionId) {
179
+ console.error('❌ No session ID provided in request URL');
180
+ res.status(400).send('Missing sessionId parameter');
181
+ return;
182
+ }
183
+ const transport = transports[sessionId];
184
+ if (!transport) {
185
+ console.error(`❌ No active transport found for session ID: ${sessionId}`);
186
+ res.status(404).send('Session not found');
187
+ return;
188
+ }
189
+ let message = req.body;
190
+ let result;
191
+ console.log(`πŸ” MCP λ©”μ‹œμ§€ 처리 쀑: ${message.method}`, JSON.stringify(message, null, 2));
192
+ try {
193
+ if (message.method === 'initialize') {
194
+ console.log('πŸš€ MCP initialize μš”μ²­ 처리 쀑...');
195
+ result = {
196
+ jsonrpc: '2.0',
197
+ id: message.id,
198
+ result: {
199
+ protocolVersion: '2024-11-05',
200
+ capabilities: {
201
+ tools: {}
202
+ },
203
+ serverInfo: {
204
+ name: 'memento-memory',
205
+ version: '0.1.0'
206
+ }
207
+ }
208
+ };
209
+ console.log('βœ… MCP initialize 응닡 생성 μ™„λ£Œ:', JSON.stringify(result, null, 2));
210
+ }
211
+ else if (message.method === 'notifications/initialized') {
212
+ console.log('πŸ”” MCP initialized μ•Œλ¦Ό μˆ˜μ‹ ');
213
+ result = {
214
+ jsonrpc: '2.0',
215
+ id: message.id,
216
+ result: {}
217
+ };
218
+ }
219
+ else if (message.method === 'tools/list') {
220
+ console.log('πŸ“‹ MCP tools/list μš”μ²­ 처리 쀑...');
221
+ try {
222
+ const toolRegistry = getToolRegistry();
223
+ const tools = toolRegistry.getAll();
224
+ console.log('πŸ” 도ꡬ λͺ©λ‘ μ‚¬μš©, 길이:', tools.length);
225
+ result = {
226
+ jsonrpc: '2.0',
227
+ id: message.id,
228
+ result: { tools }
229
+ };
230
+ console.log('βœ… MCP tools/list 응닡 생성 μ™„λ£Œ, tools 개수:', tools.length);
231
+ console.log('πŸ” 응닡 크기:', JSON.stringify(result).length, 'bytes');
232
+ // SSE 응닡 μ¦‰μ‹œ 전솑
233
+ console.log('πŸ“€ SSE 응닡 μ¦‰μ‹œ 전솑 쀑...');
234
+ if (transport && transport.res && !transport.res.writableEnded) {
235
+ const sseData = `data: ${JSON.stringify(result)}\n\n`;
236
+ transport.res.write(sseData);
237
+ console.log('βœ… SSE 응닡 μ¦‰μ‹œ 전솑 μ™„λ£Œ, 크기:', sseData.length, 'bytes');
238
+ }
239
+ else {
240
+ console.error('❌ SSE transportκ°€ μœ νš¨ν•˜μ§€ μ•ŠμŒ');
241
+ }
242
+ // HTTP 응닡 전솑
243
+ res.json({ status: 'ok' });
244
+ return;
245
+ }
246
+ catch (toolsError) {
247
+ console.error('❌ tools/list 처리 쀑 였λ₯˜:', toolsError);
248
+ const errorResult = {
249
+ jsonrpc: '2.0',
250
+ id: message.id,
251
+ error: {
252
+ code: -32603,
253
+ message: 'Internal error',
254
+ data: toolsError instanceof Error ? toolsError.message : String(toolsError)
255
+ }
256
+ };
257
+ if (transport && transport.res && !transport.res.writableEnded) {
258
+ transport.res.write(`data: ${JSON.stringify(errorResult)}\n\n`);
259
+ }
260
+ res.json({ status: 'error' });
261
+ return;
262
+ }
263
+ }
264
+ else if (message.method === 'tools/call') {
265
+ const { name, arguments: args } = message.params;
266
+ const toolRegistry = getToolRegistry();
267
+ // 도ꡬ μ»¨ν…μŠ€νŠΈ 생성
268
+ const context = {
269
+ db,
270
+ services: {
271
+ searchEngine,
272
+ hybridSearchEngine,
273
+ embeddingService
274
+ }
275
+ };
276
+ // 도ꡬ μ‹€ν–‰
277
+ const toolResult = await toolRegistry.execute(name, args, context);
278
+ result = {
279
+ jsonrpc: '2.0',
280
+ id: message.id,
281
+ result: { content: [{ type: 'text', text: JSON.stringify(toolResult) }] }
282
+ };
283
+ }
284
+ else if (message.method === 'prompts/list') {
285
+ console.log('πŸ“‹ MCP prompts/list μš”μ²­ 처리 쀑...');
286
+ const prompts = [
287
+ {
288
+ name: 'memory_injection',
289
+ description: 'κ΄€λ ¨ 기얡을 μš”μ•½ν•˜μ—¬ ν”„λ‘¬ν”„νŠΈμ— μ£Όμž…',
290
+ arguments: [
291
+ {
292
+ name: 'query',
293
+ description: '검색할 쿼리',
294
+ required: true
295
+ },
296
+ {
297
+ name: 'token_budget',
298
+ description: '토큰 μ˜ˆμ‚° (κΈ°λ³Έκ°’: 1000)',
299
+ required: false
300
+ },
301
+ {
302
+ name: 'max_memories',
303
+ description: 'μ΅œλŒ€ κΈ°μ–΅ 개수 (κΈ°λ³Έκ°’: 5)',
304
+ required: false
305
+ }
306
+ ]
307
+ }
308
+ ];
309
+ result = {
310
+ jsonrpc: '2.0',
311
+ id: message.id,
312
+ result: { prompts }
313
+ };
314
+ console.log('βœ… MCP prompts/list 응닡 생성 μ™„λ£Œ');
315
+ }
316
+ else if (message.method === 'prompts/get') {
317
+ const { name } = message.params;
318
+ if (name === 'memory_injection') {
319
+ result = {
320
+ jsonrpc: '2.0',
321
+ id: message.id,
322
+ result: {
323
+ description: 'κ΄€λ ¨ 기얡을 μš”μ•½ν•˜μ—¬ ν”„λ‘¬ν”„νŠΈμ— μ£Όμž…',
324
+ arguments: [
325
+ {
326
+ name: 'query',
327
+ description: '검색할 쿼리',
328
+ required: true
329
+ },
330
+ {
331
+ name: 'token_budget',
332
+ description: '토큰 μ˜ˆμ‚° (κΈ°λ³Έκ°’: 1000)',
333
+ required: false
334
+ },
335
+ {
336
+ name: 'max_memories',
337
+ description: 'μ΅œλŒ€ κΈ°μ–΅ 개수 (κΈ°λ³Έκ°’: 5)',
338
+ required: false
339
+ }
340
+ ]
341
+ }
342
+ };
343
+ }
344
+ else {
345
+ result = {
346
+ jsonrpc: '2.0',
347
+ id: message.id,
348
+ error: {
349
+ code: -32601,
350
+ message: 'Prompt not found'
351
+ }
352
+ };
353
+ }
354
+ }
355
+ else if (message.method === 'prompts/call') {
356
+ const { name, arguments: args } = message.params;
357
+ if (name === 'memory_injection') {
358
+ try {
359
+ // MemoryInjectionPrompt 도ꡬ μ‚¬μš©
360
+ const toolRegistry = getToolRegistry();
361
+ const context = {
362
+ db,
363
+ services: {
364
+ searchEngine,
365
+ hybridSearchEngine,
366
+ embeddingService
367
+ }
368
+ };
369
+ const promptResult = await toolRegistry.execute('memory_injection', args, context);
370
+ result = {
371
+ jsonrpc: '2.0',
372
+ id: message.id,
373
+ result: promptResult
374
+ };
375
+ }
376
+ catch (error) {
377
+ result = {
378
+ jsonrpc: '2.0',
379
+ id: message.id,
380
+ error: {
381
+ code: -32603,
382
+ message: 'Prompt execution failed',
383
+ data: error instanceof Error ? error.message : 'Unknown error'
384
+ }
385
+ };
386
+ }
387
+ }
388
+ else {
389
+ result = {
390
+ jsonrpc: '2.0',
391
+ id: message.id,
392
+ error: {
393
+ code: -32601,
394
+ message: 'Prompt not found'
395
+ }
396
+ };
397
+ }
398
+ }
399
+ else {
400
+ result = {
401
+ jsonrpc: '2.0',
402
+ id: message.id,
403
+ error: {
404
+ code: -32601,
405
+ message: 'Method not found'
406
+ }
407
+ };
408
+ }
409
+ // Send response via SSE
410
+ console.log('πŸ“€ SSE 응닡 전솑 쀑:', JSON.stringify(result).substring(0, 200) + '...');
411
+ try {
412
+ // transport 객체 μœ νš¨μ„± 확인
413
+ if (!transport || !transport.res || transport.res.writableEnded) {
414
+ console.error('❌ SSE transportκ°€ μœ νš¨ν•˜μ§€ μ•ŠμŒ');
415
+ res.status(500).json({ error: 'SSE transport invalid' });
416
+ return;
417
+ }
418
+ // SSE 응닡 전솑
419
+ const sseData = `data: ${JSON.stringify(result)}\n\n`;
420
+ transport.res.write(sseData);
421
+ console.log('βœ… SSE 응닡 전솑 μ™„λ£Œ, 크기:', sseData.length, 'bytes');
422
+ }
423
+ catch (sseError) {
424
+ console.error('❌ SSE 응닡 전솑 μ‹€νŒ¨:', sseError);
425
+ // SSE 전솑 μ‹€νŒ¨ μ‹œμ—λ„ HTTP 응닡은 정상 처리
426
+ }
427
+ // Send HTTP response
428
+ res.json({ status: 'ok' });
429
+ }
430
+ catch (error) {
431
+ console.error('❌ MCP λ©”μ‹œμ§€ 처리 μ‹€νŒ¨:', error);
432
+ const errorResponse = {
433
+ jsonrpc: '2.0',
434
+ id: message?.id || null,
435
+ error: {
436
+ code: -32603,
437
+ message: 'Internal error',
438
+ data: error instanceof Error ? error.message : 'Unknown error'
439
+ }
440
+ };
441
+ // Send error via SSE
442
+ try {
443
+ if (transport && transport.res && !transport.res.writableEnded) {
444
+ const errorSseData = `data: ${JSON.stringify(errorResponse)}\n\n`;
445
+ transport.res.write(errorSseData);
446
+ console.log('βœ… SSE μ—λŸ¬ 응닡 전솑 μ™„λ£Œ');
447
+ }
448
+ else {
449
+ console.error('❌ SSE transportκ°€ μœ νš¨ν•˜μ§€ μ•Šμ•„ μ—λŸ¬ 응닡 전솑 μ‹€νŒ¨');
450
+ }
451
+ }
452
+ catch (errorSseError) {
453
+ console.error('❌ SSE μ—λŸ¬ 응닡 전솑 μ‹€νŒ¨:', errorSseError);
454
+ }
455
+ // Send HTTP response
456
+ res.json({ status: 'error' });
457
+ }
458
+ });
459
+ // κ΄€λ¦¬μž API μ—”λ“œν¬μΈνŠΈλ“€
460
+ app.post('/admin/memory/cleanup', async (req, res) => {
461
+ try {
462
+ // λ©”λͺ¨λ¦¬ 정리 둜직 (κΈ°μ‘΄ CleanupMemoryTool 둜직)
463
+ if (!db) {
464
+ return res.status(500).json({ error: 'λ°μ΄ν„°λ² μ΄μŠ€κ°€ μ—°κ²°λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€' });
465
+ }
466
+ // κ°„λ‹¨ν•œ λ©”λͺ¨λ¦¬ 정리 κ΅¬ν˜„
467
+ const result = await db.prepare(`
468
+ DELETE FROM memory_item
469
+ WHERE pinned = FALSE
470
+ AND type = 'working'
471
+ AND created_at < datetime('now', '-2 days')
472
+ `).run();
473
+ return res.json({
474
+ message: 'λ©”λͺ¨λ¦¬ 정리 μ™„λ£Œ',
475
+ deleted_count: result.changes,
476
+ timestamp: new Date().toISOString()
477
+ });
478
+ }
479
+ catch (error) {
480
+ console.error('❌ λ©”λͺ¨λ¦¬ 정리 μ‹€νŒ¨:', error);
481
+ return res.status(500).json({
482
+ error: 'λ©”λͺ¨λ¦¬ 정리 μ‹€νŒ¨',
483
+ message: error instanceof Error ? error.message : 'Unknown error'
484
+ });
485
+ }
486
+ });
487
+ app.get('/admin/stats/forgetting', async (req, res) => {
488
+ try {
489
+ // 망각 톡계 둜직 (κΈ°μ‘΄ ForgettingStatsTool 둜직)
490
+ if (!db) {
491
+ return res.status(500).json({ error: 'λ°μ΄ν„°λ² μ΄μŠ€κ°€ μ—°κ²°λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€' });
492
+ }
493
+ const stats = await db.prepare(`
494
+ SELECT
495
+ type,
496
+ COUNT(*) as total_count,
497
+ COUNT(CASE WHEN pinned = TRUE THEN 1 END) as pinned_count,
498
+ COUNT(CASE WHEN created_at < datetime('now', '-30 days') THEN 1 END) as old_count
499
+ FROM memory_item
500
+ GROUP BY type
501
+ `).all();
502
+ return res.json({
503
+ message: '망각 톡계 쑰회 μ™„λ£Œ',
504
+ stats,
505
+ timestamp: new Date().toISOString()
506
+ });
507
+ }
508
+ catch (error) {
509
+ console.error('❌ 망각 톡계 쑰회 μ‹€νŒ¨:', error);
510
+ return res.status(500).json({
511
+ error: '망각 톡계 쑰회 μ‹€νŒ¨',
512
+ message: error instanceof Error ? error.message : 'Unknown error'
513
+ });
514
+ }
515
+ });
516
+ app.get('/admin/stats/performance', async (req, res) => {
517
+ try {
518
+ // μ„±λŠ₯ 톡계 둜직 (κΈ°μ‘΄ PerformanceStatsTool 둜직)
519
+ if (!db) {
520
+ return res.status(500).json({ error: 'λ°μ΄ν„°λ² μ΄μŠ€κ°€ μ—°κ²°λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€' });
521
+ }
522
+ const stats = await db.prepare(`
523
+ SELECT
524
+ COUNT(*) as total_memories,
525
+ COUNT(CASE WHEN type = 'working' THEN 1 END) as working_memories,
526
+ COUNT(CASE WHEN type = 'episodic' THEN 1 END) as episodic_memories,
527
+ COUNT(CASE WHEN type = 'semantic' THEN 1 END) as semantic_memories,
528
+ COUNT(CASE WHEN type = 'procedural' THEN 1 END) as procedural_memories,
529
+ COUNT(CASE WHEN pinned = TRUE THEN 1 END) as pinned_memories
530
+ FROM memory_item
531
+ `).get();
532
+ return res.json({
533
+ message: 'μ„±λŠ₯ 톡계 쑰회 μ™„λ£Œ',
534
+ stats,
535
+ timestamp: new Date().toISOString()
536
+ });
537
+ }
538
+ catch (error) {
539
+ console.error('❌ μ„±λŠ₯ 톡계 쑰회 μ‹€νŒ¨:', error);
540
+ return res.status(500).json({
541
+ error: 'μ„±λŠ₯ 톡계 쑰회 μ‹€νŒ¨',
542
+ message: error instanceof Error ? error.message : 'Unknown error'
543
+ });
544
+ }
545
+ });
546
+ app.post('/admin/database/optimize', async (req, res) => {
547
+ try {
548
+ // λ°μ΄ν„°λ² μ΄μŠ€ μ΅œμ ν™” 둜직 (κΈ°μ‘΄ DatabaseOptimizeTool 둜직)
549
+ if (!db) {
550
+ return res.status(500).json({ error: 'λ°μ΄ν„°λ² μ΄μŠ€κ°€ μ—°κ²°λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€' });
551
+ }
552
+ // VACUUM μ‹€ν–‰
553
+ await db.prepare('VACUUM').run();
554
+ // ANALYZE μ‹€ν–‰
555
+ await db.prepare('ANALYZE').run();
556
+ return res.json({
557
+ message: 'λ°μ΄ν„°λ² μ΄μŠ€ μ΅œμ ν™” μ™„λ£Œ',
558
+ timestamp: new Date().toISOString()
559
+ });
560
+ }
561
+ catch (error) {
562
+ console.error('❌ λ°μ΄ν„°λ² μ΄μŠ€ μ΅œμ ν™” μ‹€νŒ¨:', error);
563
+ return res.status(500).json({
564
+ error: 'λ°μ΄ν„°λ² μ΄μŠ€ μ΅œμ ν™” μ‹€νŒ¨',
565
+ message: error instanceof Error ? error.message : 'Unknown error'
566
+ });
567
+ }
568
+ });
569
+ app.get('/admin/stats/errors', async (req, res) => {
570
+ try {
571
+ // μ—λŸ¬ 톡계 둜직 (κΈ°μ‘΄ errorStatsTool 둜직)
572
+ res.json({
573
+ message: 'μ—λŸ¬ 톡계 쑰회 μ™„λ£Œ',
574
+ stats: {
575
+ total_errors: 0,
576
+ recent_errors: [],
577
+ error_types: {}
578
+ },
579
+ timestamp: new Date().toISOString()
580
+ });
581
+ }
582
+ catch (error) {
583
+ console.error('❌ μ—λŸ¬ 톡계 쑰회 μ‹€νŒ¨:', error);
584
+ res.status(500).json({
585
+ error: 'μ—λŸ¬ 톡계 쑰회 μ‹€νŒ¨',
586
+ message: error instanceof Error ? error.message : 'Unknown error'
587
+ });
588
+ }
589
+ });
590
+ app.post('/admin/errors/resolve', async (req, res) => {
591
+ try {
592
+ const { errorId, resolvedBy, reason } = req.body;
593
+ // μ—λŸ¬ ν•΄κ²° 둜직 (κΈ°μ‘΄ resolveErrorTool 둜직)
594
+ res.json({
595
+ message: 'μ—λŸ¬ ν•΄κ²° μ™„λ£Œ',
596
+ errorId,
597
+ resolvedBy,
598
+ reason,
599
+ timestamp: new Date().toISOString()
600
+ });
601
+ }
602
+ catch (error) {
603
+ console.error('❌ μ—λŸ¬ ν•΄κ²° μ‹€νŒ¨:', error);
604
+ res.status(500).json({
605
+ error: 'μ—λŸ¬ ν•΄κ²° μ‹€νŒ¨',
606
+ message: error instanceof Error ? error.message : 'Unknown error'
607
+ });
608
+ }
609
+ });
610
+ app.get('/admin/alerts/performance', async (req, res) => {
611
+ try {
612
+ // μ„±λŠ₯ μ•Œλ¦Ό 둜직 (κΈ°μ‘΄ performanceAlertsTool 둜직)
613
+ res.json({
614
+ message: 'μ„±λŠ₯ μ•Œλ¦Ό 쑰회 μ™„λ£Œ',
615
+ alerts: [],
616
+ timestamp: new Date().toISOString()
617
+ });
618
+ }
619
+ catch (error) {
620
+ console.error('❌ μ„±λŠ₯ μ•Œλ¦Ό 쑰회 μ‹€νŒ¨:', error);
621
+ res.status(500).json({
622
+ error: 'μ„±λŠ₯ μ•Œλ¦Ό 쑰회 μ‹€νŒ¨',
623
+ message: error instanceof Error ? error.message : 'Unknown error'
624
+ });
625
+ }
626
+ });
627
+ // 배치 μŠ€μΌ€μ€„λŸ¬ 관리 API
628
+ app.get('/admin/batch/status', async (req, res) => {
629
+ try {
630
+ const batchScheduler = getBatchScheduler();
631
+ const status = batchScheduler.getStatus();
632
+ res.json({
633
+ message: '배치 μŠ€μΌ€μ€„λŸ¬ μƒνƒœ 쑰회 μ™„λ£Œ',
634
+ status,
635
+ timestamp: new Date().toISOString()
636
+ });
637
+ }
638
+ catch (error) {
639
+ console.error('❌ 배치 μŠ€μΌ€μ€„λŸ¬ μƒνƒœ 쑰회 μ‹€νŒ¨:', error);
640
+ res.status(500).json({
641
+ error: '배치 μŠ€μΌ€μ€„λŸ¬ μƒνƒœ 쑰회 μ‹€νŒ¨',
642
+ message: error instanceof Error ? error.message : 'Unknown error'
643
+ });
644
+ }
645
+ });
646
+ app.post('/admin/batch/run', async (req, res) => {
647
+ try {
648
+ const { jobType } = req.body;
649
+ if (!jobType || !['cleanup', 'monitoring'].includes(jobType)) {
650
+ return res.status(400).json({
651
+ error: 'Invalid job type. Must be "cleanup" or "monitoring"'
652
+ });
653
+ }
654
+ const batchScheduler = getBatchScheduler();
655
+ const result = await batchScheduler.runJob(jobType);
656
+ return res.json({
657
+ message: `배치 μž‘μ—… ${jobType} μ‹€ν–‰ μ™„λ£Œ`,
658
+ result,
659
+ timestamp: new Date().toISOString()
660
+ });
661
+ }
662
+ catch (error) {
663
+ console.error('❌ 배치 μž‘μ—… μ‹€ν–‰ μ‹€νŒ¨:', error);
664
+ return res.status(500).json({
665
+ error: '배치 μž‘μ—… μ‹€ν–‰ μ‹€νŒ¨',
666
+ message: error instanceof Error ? error.message : 'Unknown error'
667
+ });
668
+ }
669
+ });
670
+ // μ„±λŠ₯ λͺ¨λ‹ˆν„°λ§ API
671
+ app.get('/admin/performance/metrics', async (req, res) => {
672
+ try {
673
+ const monitor = getPerformanceMonitor();
674
+ const metrics = await monitor.collectMetrics();
675
+ res.json({
676
+ message: 'μ„±λŠ₯ μ§€ν‘œ μˆ˜μ§‘ μ™„λ£Œ',
677
+ metrics,
678
+ timestamp: new Date().toISOString()
679
+ });
680
+ }
681
+ catch (error) {
682
+ console.error('❌ μ„±λŠ₯ μ§€ν‘œ μˆ˜μ§‘ μ‹€νŒ¨:', error);
683
+ res.status(500).json({
684
+ error: 'μ„±λŠ₯ μ§€ν‘œ μˆ˜μ§‘ μ‹€νŒ¨',
685
+ message: error instanceof Error ? error.message : 'Unknown error'
686
+ });
687
+ }
688
+ });
689
+ app.get('/admin/performance/alerts', async (req, res) => {
690
+ try {
691
+ const monitor = getPerformanceMonitor();
692
+ const alerts = monitor.getActiveAlerts();
693
+ res.json({
694
+ message: 'μ„±λŠ₯ μ•Œλ¦Ό 쑰회 μ™„λ£Œ',
695
+ alerts,
696
+ count: alerts.length,
697
+ timestamp: new Date().toISOString()
698
+ });
699
+ }
700
+ catch (error) {
701
+ console.error('❌ μ„±λŠ₯ μ•Œλ¦Ό 쑰회 μ‹€νŒ¨:', error);
702
+ res.status(500).json({
703
+ error: 'μ„±λŠ₯ μ•Œλ¦Ό 쑰회 μ‹€νŒ¨',
704
+ message: error instanceof Error ? error.message : 'Unknown error'
705
+ });
706
+ }
707
+ });
708
+ app.get('/admin/performance/summary', async (req, res) => {
709
+ try {
710
+ const monitor = getPerformanceMonitor();
711
+ const summary = monitor.getPerformanceSummary();
712
+ res.json({
713
+ message: 'μ„±λŠ₯ μš”μ•½ 쑰회 μ™„λ£Œ',
714
+ summary,
715
+ timestamp: new Date().toISOString()
716
+ });
717
+ }
718
+ catch (error) {
719
+ console.error('❌ μ„±λŠ₯ μš”μ•½ 쑰회 μ‹€νŒ¨:', error);
720
+ res.status(500).json({
721
+ error: 'μ„±λŠ₯ μš”μ•½ 쑰회 μ‹€νŒ¨',
722
+ message: error instanceof Error ? error.message : 'Unknown error'
723
+ });
724
+ }
725
+ });
726
+ app.post('/admin/performance/alerts/:alertId/resolve', async (req, res) => {
727
+ try {
728
+ const { alertId } = req.params;
729
+ const monitor = getPerformanceMonitor();
730
+ const resolved = monitor.resolveAlert(alertId);
731
+ if (resolved) {
732
+ res.json({
733
+ message: 'μ•Œλ¦Ό ν•΄κ²° μ™„λ£Œ',
734
+ alertId,
735
+ timestamp: new Date().toISOString()
736
+ });
737
+ }
738
+ else {
739
+ res.status(404).json({
740
+ error: 'μ•Œλ¦Όμ„ 찾을 수 μ—†μŠ΅λ‹ˆλ‹€',
741
+ alertId
742
+ });
743
+ }
744
+ }
745
+ catch (error) {
746
+ console.error('❌ μ•Œλ¦Ό ν•΄κ²° μ‹€νŒ¨:', error);
747
+ res.status(500).json({
748
+ error: 'μ•Œλ¦Ό ν•΄κ²° μ‹€νŒ¨',
749
+ message: error instanceof Error ? error.message : 'Unknown error'
750
+ });
751
+ }
752
+ });
753
+ // μ„œλ²„ μ΄ˆκΈ°ν™”
754
+ async function initializeServer() {
755
+ try {
756
+ console.log('πŸš€ HTTP/WebSocket MCP μ„œλ²„ v2 μ‹œμž‘ 쀑...');
757
+ // μ„€μ • 검증
758
+ validateConfig();
759
+ // λ°μ΄ν„°λ² μ΄μŠ€ μ΄ˆκΈ°ν™”
760
+ db = await initializeDatabase();
761
+ // 검색 μ—”μ§„ μ΄ˆκΈ°ν™”
762
+ searchEngine = new SearchEngine();
763
+ hybridSearchEngine = new HybridSearchEngine();
764
+ vectorSearchEngine = getVectorSearchEngine();
765
+ vectorSearchEngine.initialize(db);
766
+ embeddingService = new MemoryEmbeddingService();
767
+ // 배치 μŠ€μΌ€μ€„λŸ¬ μ‹œμž‘
768
+ const batchScheduler = getBatchScheduler();
769
+ await batchScheduler.start(db);
770
+ console.log('⏰ 배치 μŠ€μΌ€μ€„λŸ¬ μ‹œμž‘λ¨');
771
+ // μž„λ² λ”© ν”„λ‘œλ°”μ΄λ” 정보 ν‘œμ‹œ
772
+ console.log(`πŸ”§ μž„λ² λ”© ν”„λ‘œλ°”μ΄λ”: ${mementoConfig.embeddingProvider.toUpperCase()}`);
773
+ if (mementoConfig.embeddingProvider === 'openai' && mementoConfig.openaiApiKey) {
774
+ console.log(` πŸ“ λͺ¨λΈ: ${mementoConfig.openaiModel} (${mementoConfig.embeddingDimensions}차원)`);
775
+ }
776
+ else if (mementoConfig.embeddingProvider === 'gemini' && mementoConfig.geminiApiKey) {
777
+ console.log(` πŸ“ λͺ¨λΈ: ${mementoConfig.geminiModel} (${mementoConfig.embeddingDimensions}차원)`);
778
+ }
779
+ else if (mementoConfig.embeddingProvider === 'lightweight') {
780
+ console.log(` πŸ“ λͺ¨λΈ: lightweight-hybrid (512차원)`);
781
+ }
782
+ console.log('βœ… μ„œλ²„ μ΄ˆκΈ°ν™” μ™„λ£Œ');
783
+ console.log(`πŸ“Š μ„œλ²„: ${mementoConfig.serverName} v${mementoConfig.serverVersion}`);
784
+ console.log(`πŸ—„οΈ λ°μ΄ν„°λ² μ΄μŠ€: ${mementoConfig.dbPath}`);
785
+ }
786
+ catch (error) {
787
+ console.error('❌ μ„œλ²„ μ΄ˆκΈ°ν™” μ‹€νŒ¨:', error);
788
+ process.exit(1);
789
+ }
790
+ }
791
+ // 정리 ν•¨μˆ˜
792
+ let isCleaningUp = false;
793
+ async function cleanup() {
794
+ if (isCleaningUp) {
795
+ return;
796
+ }
797
+ isCleaningUp = true;
798
+ try {
799
+ // 배치 μŠ€μΌ€μ€„λŸ¬ 쀑지
800
+ const batchScheduler = getBatchScheduler();
801
+ batchScheduler.stop();
802
+ console.log('⏰ 배치 μŠ€μΌ€μ€„λŸ¬ 쀑지됨');
803
+ if (db) {
804
+ closeDatabase(db);
805
+ db = null;
806
+ }
807
+ console.log('πŸ‘‹ HTTP/WebSocket MCP μ„œλ²„ v2 μ’…λ£Œ');
808
+ }
809
+ catch (error) {
810
+ console.error('❌ 정리 쀑 였λ₯˜:', error);
811
+ }
812
+ }
813
+ // ν”„λ‘œμ„ΈμŠ€ μ’…λ£Œ μ‹œ 정리
814
+ let cleanupRegistered = false;
815
+ function registerCleanupHandlers() {
816
+ if (cleanupRegistered) {
817
+ return;
818
+ }
819
+ cleanupRegistered = true;
820
+ process.on('SIGINT', async () => {
821
+ await cleanup();
822
+ process.exit(0);
823
+ });
824
+ process.on('SIGTERM', async () => {
825
+ await cleanup();
826
+ process.exit(0);
827
+ });
828
+ process.on('uncaughtException', async (error) => {
829
+ console.error('❌ μ˜ˆμƒμΉ˜ λͺ»ν•œ 였λ₯˜:', error);
830
+ await cleanup();
831
+ process.exit(1);
832
+ });
833
+ }
834
+ // WebSocket μ„œλ²„ μ„€μ •
835
+ const wss = new WebSocketServer({ server });
836
+ wss.on('connection', (ws) => {
837
+ console.log('πŸ”— WebSocket ν΄λΌμ΄μ–ΈνŠΈ 연결됨');
838
+ ws.on('message', async (data) => {
839
+ let message;
840
+ try {
841
+ message = JSON.parse(data.toString());
842
+ if (message.method === 'tools/list') {
843
+ const toolRegistry = getToolRegistry();
844
+ const tools = toolRegistry.getAll();
845
+ ws.send(JSON.stringify({
846
+ jsonrpc: '2.0',
847
+ id: message.id,
848
+ result: { tools }
849
+ }));
850
+ }
851
+ else if (message.method === 'tools/call') {
852
+ const { name, arguments: args } = message.params;
853
+ const toolRegistry = getToolRegistry();
854
+ // 도ꡬ μ»¨ν…μŠ€νŠΈ 생성
855
+ const context = {
856
+ db,
857
+ services: {
858
+ searchEngine,
859
+ hybridSearchEngine,
860
+ embeddingService
861
+ }
862
+ };
863
+ // 도ꡬ μ‹€ν–‰
864
+ const result = await toolRegistry.execute(name, args, context);
865
+ ws.send(JSON.stringify({
866
+ jsonrpc: '2.0',
867
+ id: message.id,
868
+ result: { content: [{ type: 'text', text: JSON.stringify(result) }] }
869
+ }));
870
+ }
871
+ }
872
+ catch (error) {
873
+ console.error('❌ WebSocket λ©”μ‹œμ§€ 처리 μ‹€νŒ¨:', error);
874
+ ws.send(JSON.stringify({
875
+ jsonrpc: '2.0',
876
+ id: message?.id || null,
877
+ error: {
878
+ code: -32603,
879
+ message: 'Internal error',
880
+ data: error instanceof Error ? error.message : 'Unknown error'
881
+ }
882
+ }));
883
+ }
884
+ });
885
+ ws.on('close', () => {
886
+ console.log('πŸ”Œ WebSocket ν΄λΌμ΄μ–ΈνŠΈ μ—°κ²° ν•΄μ œλ¨');
887
+ });
888
+ ws.on('error', (error) => {
889
+ console.error('❌ WebSocket μ—λŸ¬:', error);
890
+ });
891
+ });
892
+ // μ„œλ²„ μ‹œμž‘
893
+ const PORT = process.env.PORT || 9001;
894
+ async function startServer() {
895
+ await initializeServer();
896
+ // 정리 ν•Έλ“€λŸ¬ 등둝
897
+ registerCleanupHandlers();
898
+ // Express app을 μ‚¬μš©ν•˜μ—¬ λͺ¨λ“  μΈν„°νŽ˜μ΄μŠ€μ— 바인딩
899
+ app.listen(Number(PORT), '0.0.0.0', () => {
900
+ console.log(`🌐 HTTP μ„œλ²„: http://0.0.0.0:${PORT}`);
901
+ console.log(`πŸ”Œ WebSocket μ„œλ²„: ws://0.0.0.0:${PORT}`);
902
+ console.log(`πŸ“‹ API λ¬Έμ„œ: http://0.0.0.0:${PORT}/tools`);
903
+ console.log(`❀️ ν—¬μŠ€ 체크: http://0.0.0.0:${PORT}/health`);
904
+ });
905
+ // μΆ”κ°€: λͺ¨λ“  μΈν„°νŽ˜μ΄μŠ€μ— 바인딩 확인
906
+ server.on('listening', () => {
907
+ const address = server.address();
908
+ if (address && typeof address === 'object') {
909
+ console.log(`πŸ”— μ„œλ²„κ°€ ${address.address}:${address.port}에 바인딩됨`);
910
+ }
911
+ });
912
+ }
913
+ // μ„œλ²„ μ‹œμž‘
914
+ if (process.argv[1] && (process.argv[1].includes('http-server'))) {
915
+ startServer().catch(error => {
916
+ console.error('❌ μ„œλ²„ μ‹œμž‘ μ‹€νŒ¨:', error);
917
+ process.exit(1);
918
+ });
919
+ }
920
+ export const __test = {
921
+ setTestDependencies,
922
+ getApp: () => app,
923
+ getServer: () => server,
924
+ getDatabase: () => db,
925
+ getSearchEngine: () => searchEngine,
926
+ getHybridSearchEngine: () => hybridSearchEngine,
927
+ getEmbeddingService: () => embeddingService
928
+ };
929
+ export { startServer, cleanup };
930
+ //# sourceMappingURL=http-server.js.map