@ninebone/mcp 0.1.26

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 (41) hide show
  1. package/README.kr.md +71 -0
  2. package/README.md +72 -0
  3. package/bak/generate-query.md +28 -0
  4. package/bak/generator-source-mapper.md +123 -0
  5. package/bak/mcp-server.js +498 -0
  6. package/bak/nomenu-navigator.md +16 -0
  7. package/bak/system-brain.md +62 -0
  8. package/bak/table-filter.md +21 -0
  9. package/package.json +33 -0
  10. package/prompts/menu/generate-menu.md +89 -0
  11. package/prompts/source/generate-source-controller.md +120 -0
  12. package/prompts/source/generate-source-mapper.mysql.md +97 -0
  13. package/prompts/source/generate-source-mapper.oracle.md +90 -0
  14. package/prompts/source/generate-source-mapper.postgre.md +89 -0
  15. package/prompts/source/generate-source-service.md +116 -0
  16. package/prompts/source/generate-source-ui-react.md +174 -0
  17. package/prompts/system/generate-source-brain.md +57 -0
  18. package/prompts/system/modify-source-brain.md +50 -0
  19. package/prompts/system/system-brain.md +88 -0
  20. package/src/ai/AIProcessor.js +85 -0
  21. package/src/ai/AIService.js +24 -0
  22. package/src/core/init.js +116 -0
  23. package/src/database/config/database.js +42 -0
  24. package/src/database/core/DatabaseManager.js +115 -0
  25. package/src/database/core/Dialects.js +66 -0
  26. package/src/database/core/PoolManager.js +92 -0
  27. package/src/drivers/mysql.js +0 -0
  28. package/src/index.js +38 -0
  29. package/src/mcp/loaders/promptLoader.js +62 -0
  30. package/src/mcp/mcp-server.js +129 -0
  31. package/src/mcp/tools/generateSourceBrainTool.js +179 -0
  32. package/src/mcp/tools/modifySourceBrainTool.js +283 -0
  33. package/src/mcp/tools/staticTools.js +29 -0
  34. package/src/mcp/tools/systemBrain.js +182 -0
  35. package/src/mcp/utils/mcp-utils.js +30 -0
  36. package/src/mcp-handler.js +131 -0
  37. package/src/services/NoMenuService.js +43 -0
  38. package/src/services/QueryService.js +26 -0
  39. package/src/services/SourceService.js +32 -0
  40. package/src/utils/CustomWsTransport.js +52 -0
  41. package/src/utils/asyncHandler.js +13 -0
@@ -0,0 +1,43 @@
1
+ import express from 'express';
2
+ import { asyncHandler } from '../utils/asyncHandler.js';
3
+
4
+ export class NoMenuService {
5
+ constructor(ai) {
6
+ this.ai = ai;
7
+ this.routes = []; // React 등에서 주입받은 메뉴 정보
8
+
9
+ console.log(ai);
10
+ }
11
+
12
+ /**
13
+ * 클라이언트(React/HTML)로부터 Route 정보를 업데이트받는 메서드
14
+ */
15
+ setRoutes(routes) {
16
+ this.routes = routes;
17
+ console.log(`[NoMenu] ${routes.length}개의 경로 정보가 로드되었습니다.`);
18
+ }
19
+
20
+ getRouter() {
21
+ const router = express.Router();
22
+
23
+ // 자연어로 이동할 경로 찾기
24
+ router.post('/go', asyncHandler(async (req, res) => {
25
+ const { question, currentRoutes } = req.body;
26
+
27
+ // 만약 요청 시점에 routes를 같이 보냈다면 업데이트
28
+ const targetRoutes = currentRoutes || this.routes;
29
+
30
+ if (!targetRoutes || targetRoutes.length === 0) {
31
+ throw new Error("참조할 Route 정보가 없습니다.");
32
+ }
33
+
34
+ // AI에게 질문과 Route 정보를 던져 최적의 경로를 받아냄
35
+ const result = await this.ai.processNavigation(question, targetRoutes);
36
+
37
+ // result는 { path: '/precedents', reason: '...' } 형태라고 가정
38
+ res.json({ success: true, ...result });
39
+ }));
40
+
41
+ return router;
42
+ }
43
+ }
@@ -0,0 +1,26 @@
1
+ import express from 'express';
2
+ import { asyncHandler, sendSuccess } from '../utils/asyncHandler.js';
3
+
4
+ export class QueryService {
5
+ constructor(db, ai, aiService) {
6
+ this.db = db;
7
+ this.ai = ai;
8
+ this.aiService = aiService;
9
+ }
10
+
11
+ getRouter() {
12
+ const router = express.Router();
13
+
14
+ // 1. 자연어 질의
15
+ router.post('/ask', asyncHandler(async (req, res) => {
16
+ const { question } = req.body;
17
+ if (!question) throw new Error("질문을 입력해주세요.");
18
+
19
+ const result = await this.aiService.processNaturalLanguageQuery(question);
20
+ // aiService 결과에 이미 여러 필드가 있으므로 펼쳐서 보냄
21
+ res.json({ success: true, ...result });
22
+ }));
23
+
24
+ return router;
25
+ }
26
+ }
@@ -0,0 +1,32 @@
1
+ import express from 'express';
2
+ import { asyncHandler } from '../utils/asyncHandler.js';
3
+
4
+ // SourceService.js
5
+ export class SourceService {
6
+ constructor(aiService) {
7
+ this.aiService = aiService;
8
+ }
9
+
10
+ getRouter() {
11
+ const router = express.Router();
12
+
13
+ // [공정 1] 분석: 현재 Route 정보를 주면 필요한 추가 기능을 리스트업
14
+ router.post('/missing', asyncHandler(async (req, res) => {
15
+ const { routes, prompt } = req.body; // 프런트에서 관리하는 route JSON
16
+ console.log(routes, prompt);
17
+
18
+ const result = await this.aiService.processMissingSources(routes, prompt);
19
+ res.json(result);
20
+ }));
21
+
22
+ // [공정 2] 생성: 특정 Task를 선택하면 실제 소스 코드를 생성 (추후 구현)
23
+ router.post('/generate', asyncHandler(async (req, res) => {
24
+ const { task } = req.body;
25
+ // task 정보를 바탕으로 소스 생성 로직 실행
26
+ const generated = await this.aiService.processSourceGeneration(task);
27
+ res.json({ success: true, generated });
28
+ }));
29
+
30
+ return router;
31
+ }
32
+ }
@@ -0,0 +1,52 @@
1
+ // CustomWsTransport.js
2
+ export class CustomWsTransport {
3
+ constructor(ws) {
4
+ this.ws = ws;
5
+ this.onmessage = null;
6
+ this.onclose = null;
7
+ this.onerror = null;
8
+ }
9
+
10
+ async start() {
11
+ // [중요] 메시지 수신 리스너를 즉시 연결
12
+ this.ws.on('message', (data) => {
13
+ if (this.onmessage) {
14
+ try {
15
+ const message = JSON.parse(data.toString());
16
+ this.onmessage(message);
17
+ } catch (err) {
18
+ console.error("❌ 메시지 파싱 에러:", err);
19
+ }
20
+ }
21
+ });
22
+
23
+ this.ws.on('close', () => {
24
+ if (this.onclose) this.onclose();
25
+ });
26
+
27
+ this.ws.on('error', (error) => {
28
+ if (this.onerror) this.onerror(error);
29
+ });
30
+
31
+ // 이미 연결된 상태라면 바로 resolve
32
+ if (this.ws.readyState === 1) {
33
+ return Promise.resolve();
34
+ }
35
+
36
+ // 연결 대기
37
+ return new Promise((resolve, reject) => {
38
+ this.ws.once('open', resolve);
39
+ this.ws.once('error', reject);
40
+ });
41
+ }
42
+
43
+ async send(message) {
44
+ if (this.ws.readyState === 1) {
45
+ this.ws.send(JSON.stringify(message));
46
+ }
47
+ }
48
+
49
+ async close() {
50
+ this.ws.close();
51
+ }
52
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * 비동기 컨트롤러의 에러를 캐치하여 공통 에러 핸들러로 넘겨주는 래퍼
3
+ */
4
+ export const asyncHandler = (fn) => (req, res, next) => {
5
+ Promise.resolve(fn(req, res, next)).catch(next);
6
+ };
7
+
8
+ /**
9
+ * 표준 응답 포맷 헬퍼
10
+ */
11
+ export const sendSuccess = (res, data, extra = {}) => {
12
+ res.json({ success: true, data, ...extra });
13
+ };