@chnxthr/knowledge-mcp 0.0.0-stage → 0.3.1
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.
- package/LICENSE +21 -0
- package/README.md +37 -2
- package/dist/bootstrap.d.ts +1 -0
- package/dist/bootstrap.js +18 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +5 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/auth.d.ts +38 -0
- package/dist/core/auth.js +93 -0
- package/dist/core/auth.js.map +1 -0
- package/dist/core/config.d.ts +259 -0
- package/dist/core/config.js +172 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/context.d.ts +25 -0
- package/dist/core/context.js +37 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/env.d.ts +2 -0
- package/dist/core/env.js +5 -0
- package/dist/core/env.js.map +1 -0
- package/dist/core/log_mask.d.ts +10 -0
- package/dist/core/log_mask.js +88 -0
- package/dist/core/log_mask.js.map +1 -0
- package/dist/core/oauth.d.ts +46 -0
- package/dist/core/oauth.js +507 -0
- package/dist/core/oauth.js.map +1 -0
- package/dist/core/paths.d.ts +5 -0
- package/dist/core/paths.js +47 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/scope.d.ts +28 -0
- package/dist/core/scope.js +54 -0
- package/dist/core/scope.js.map +1 -0
- package/dist/core/upstream.d.ts +30 -0
- package/dist/core/upstream.js +164 -0
- package/dist/core/upstream.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin/define.d.ts +144 -0
- package/dist/plugin/define.js +44 -0
- package/dist/plugin/define.js.map +1 -0
- package/dist/plugin/load.d.ts +2 -0
- package/dist/plugin/load.js +41 -0
- package/dist/plugin/load.js.map +1 -0
- package/dist/plugin/ping.d.ts +9 -0
- package/dist/plugin/ping.js +29 -0
- package/dist/plugin/ping.js.map +1 -0
- package/dist/plugin/registry.d.ts +62 -0
- package/dist/plugin/registry.js +248 -0
- package/dist/plugin/registry.js.map +1 -0
- package/dist/plugin/result.d.ts +20 -0
- package/dist/plugin/result.js +59 -0
- package/dist/plugin/result.js.map +1 -0
- package/dist/plugins/drive/chunker.d.ts +28 -0
- package/dist/plugins/drive/chunker.js +356 -0
- package/dist/plugins/drive/chunker.js.map +1 -0
- package/dist/plugins/drive/clean_text.d.ts +13 -0
- package/dist/plugins/drive/clean_text.js +31 -0
- package/dist/plugins/drive/clean_text.js.map +1 -0
- package/dist/plugins/drive/client.d.ts +94 -0
- package/dist/plugins/drive/client.js +220 -0
- package/dist/plugins/drive/client.js.map +1 -0
- package/dist/plugins/drive/embeddings.d.ts +15 -0
- package/dist/plugins/drive/embeddings.js +118 -0
- package/dist/plugins/drive/embeddings.js.map +1 -0
- package/dist/plugins/drive/exclude.d.ts +11 -0
- package/dist/plugins/drive/exclude.js +36 -0
- package/dist/plugins/drive/exclude.js.map +1 -0
- package/dist/plugins/drive/extract_text.d.ts +26 -0
- package/dist/plugins/drive/extract_text.js +95 -0
- package/dist/plugins/drive/extract_text.js.map +1 -0
- package/dist/plugins/drive/get_token.d.ts +5 -0
- package/dist/plugins/drive/get_token.js +128 -0
- package/dist/plugins/drive/get_token.js.map +1 -0
- package/dist/plugins/drive/index.d.ts +5 -0
- package/dist/plugins/drive/index.js +72 -0
- package/dist/plugins/drive/index.js.map +1 -0
- package/dist/plugins/drive/indexer.d.ts +69 -0
- package/dist/plugins/drive/indexer.js +204 -0
- package/dist/plugins/drive/indexer.js.map +1 -0
- package/dist/plugins/drive/mathpix.d.ts +4 -0
- package/dist/plugins/drive/mathpix.js +102 -0
- package/dist/plugins/drive/mathpix.js.map +1 -0
- package/dist/plugins/drive/ooxml.d.ts +17 -0
- package/dist/plugins/drive/ooxml.js +152 -0
- package/dist/plugins/drive/ooxml.js.map +1 -0
- package/dist/plugins/drive/path.d.ts +40 -0
- package/dist/plugins/drive/path.js +87 -0
- package/dist/plugins/drive/path.js.map +1 -0
- package/dist/plugins/drive/qdrant.d.ts +123 -0
- package/dist/plugins/drive/qdrant.js +148 -0
- package/dist/plugins/drive/qdrant.js.map +1 -0
- package/dist/plugins/drive/reindex.d.ts +2 -0
- package/dist/plugins/drive/reindex.js +263 -0
- package/dist/plugins/drive/reindex.js.map +1 -0
- package/dist/plugins/drive/settings.d.ts +11 -0
- package/dist/plugins/drive/settings.js +13 -0
- package/dist/plugins/drive/settings.js.map +1 -0
- package/dist/plugins/drive/sync.d.ts +16 -0
- package/dist/plugins/drive/sync.js +139 -0
- package/dist/plugins/drive/sync.js.map +1 -0
- package/dist/plugins/drive/sync_state.d.ts +3 -0
- package/dist/plugins/drive/sync_state.js +26 -0
- package/dist/plugins/drive/sync_state.js.map +1 -0
- package/dist/plugins/drive/tools/list_drive_folder.d.ts +104 -0
- package/dist/plugins/drive/tools/list_drive_folder.js +221 -0
- package/dist/plugins/drive/tools/list_drive_folder.js.map +1 -0
- package/dist/plugins/drive/tools/read_drive_file.d.ts +66 -0
- package/dist/plugins/drive/tools/read_drive_file.js +206 -0
- package/dist/plugins/drive/tools/read_drive_file.js.map +1 -0
- package/dist/plugins/drive/tools/search_drive.d.ts +52 -0
- package/dist/plugins/drive/tools/search_drive.js +78 -0
- package/dist/plugins/drive/tools/search_drive.js.map +1 -0
- package/dist/plugins/drive/tools/semantic_search_drive.d.ts +109 -0
- package/dist/plugins/drive/tools/semantic_search_drive.js +228 -0
- package/dist/plugins/drive/tools/semantic_search_drive.js.map +1 -0
- package/dist/plugins/github/index.d.ts +1 -0
- package/dist/plugins/github/index.js +27 -0
- package/dist/plugins/github/index.js.map +1 -0
- package/dist/plugins/github/repo_tree.d.ts +57 -0
- package/dist/plugins/github/repo_tree.js +123 -0
- package/dist/plugins/github/repo_tree.js.map +1 -0
- package/dist/plugins/index.d.ts +11 -0
- package/dist/plugins/index.js +7 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/railway/index.d.ts +1 -0
- package/dist/plugins/railway/index.js +21 -0
- package/dist/plugins/railway/index.js.map +1 -0
- package/dist/plugins/railway/tools.d.ts +114 -0
- package/dist/plugins/railway/tools.js +165 -0
- package/dist/plugins/railway/tools.js.map +1 -0
- package/dist/plugins/slack/api.d.ts +63 -0
- package/dist/plugins/slack/api.js +280 -0
- package/dist/plugins/slack/api.js.map +1 -0
- package/dist/plugins/slack/index.d.ts +1 -0
- package/dist/plugins/slack/index.js +80 -0
- package/dist/plugins/slack/index.js.map +1 -0
- package/dist/plugins/slack/tools/slack_files.d.ts +87 -0
- package/dist/plugins/slack/tools/slack_files.js +204 -0
- package/dist/plugins/slack/tools/slack_files.js.map +1 -0
- package/dist/plugins/slack/tools/slack_list_channels.d.ts +46 -0
- package/dist/plugins/slack/tools/slack_list_channels.js +197 -0
- package/dist/plugins/slack/tools/slack_list_channels.js.map +1 -0
- package/dist/plugins/slack/tools/slack_read_channel.d.ts +56 -0
- package/dist/plugins/slack/tools/slack_read_channel.js +150 -0
- package/dist/plugins/slack/tools/slack_read_channel.js.map +1 -0
- package/dist/plugins/slack/tools/slack_search.d.ts +53 -0
- package/dist/plugins/slack/tools/slack_search.js +132 -0
- package/dist/plugins/slack/tools/slack_search.js.map +1 -0
- package/dist/run.d.ts +8 -0
- package/dist/run.js +270 -0
- package/dist/run.js.map +1 -0
- package/dist/server/http.d.ts +5 -0
- package/dist/server/http.js +406 -0
- package/dist/server/http.js.map +1 -0
- package/dist/server/identity.d.ts +17 -0
- package/dist/server/identity.js +47 -0
- package/dist/server/identity.js.map +1 -0
- package/dist/server/mcp.d.ts +7 -0
- package/dist/server/mcp.js +55 -0
- package/dist/server/mcp.js.map +1 -0
- package/dist/server/stdio.d.ts +2 -0
- package/dist/server/stdio.js +40 -0
- package/dist/server/stdio.js.map +1 -0
- package/dist/store/index.d.ts +11 -0
- package/dist/store/index.js +31 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/keys.d.ts +9 -0
- package/dist/store/keys.js +32 -0
- package/dist/store/keys.js.map +1 -0
- package/dist/store/sqlite.d.ts +38 -0
- package/dist/store/sqlite.js +316 -0
- package/dist/store/sqlite.js.map +1 -0
- package/dist/store/supabase.d.ts +35 -0
- package/dist/store/supabase.js +269 -0
- package/dist/store/supabase.js.map +1 -0
- package/dist/store/supabase_client.d.ts +10 -0
- package/dist/store/supabase_client.js +31 -0
- package/dist/store/supabase_client.js.map +1 -0
- package/dist/store/tool_log.d.ts +12 -0
- package/dist/store/tool_log.js +8 -0
- package/dist/store/tool_log.js.map +1 -0
- package/dist/store/types.d.ts +96 -0
- package/dist/store/types.js +2 -0
- package/dist/store/types.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +11 -0
- package/dist/version.js.map +1 -0
- package/package.json +80 -4
- package/sql/supabase.sql +185 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search_drive.js","sourceRoot":"","sources":["../../../../src/plugins/drive/tools/search_drive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* semantic_search_drive — 자연어 질의 → Qdrant vector search → top-K chunks.
|
|
3
|
+
*
|
|
4
|
+
* Pipeline:
|
|
5
|
+
* 1. embed query (OpenAI text-embedding-3-small, 1536d)
|
|
6
|
+
* 2. Qdrant search (Cosine, optional payload filter)
|
|
7
|
+
* 3. payload 를 markdown 으로 포맷 (citation drive link 포함)
|
|
8
|
+
*
|
|
9
|
+
* Latency target (P95):
|
|
10
|
+
* - embed: 200~400ms (OpenAI API)
|
|
11
|
+
* - search: 10~30ms (Qdrant HNSW)
|
|
12
|
+
* - total: 300~500ms
|
|
13
|
+
*
|
|
14
|
+
* Indexing 안 됐으면 `knowledge-mcp drive reindex` 안내.
|
|
15
|
+
*/
|
|
16
|
+
import { z } from 'zod';
|
|
17
|
+
declare const inputSchema: z.ZodObject<{
|
|
18
|
+
query: z.ZodString;
|
|
19
|
+
topK: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
20
|
+
fileType: z.ZodOptional<z.ZodEnum<["dev_log", "decision", "rule", "template", "biz", "other"]>>;
|
|
21
|
+
source: z.ZodOptional<z.ZodEnum<["dev", "biz"]>>;
|
|
22
|
+
cluster: z.ZodOptional<z.ZodString>;
|
|
23
|
+
hasImage: z.ZodOptional<z.ZodBoolean>;
|
|
24
|
+
docStatus: z.ZodOptional<z.ZodEnum<["living", "implemented", "accepted", "exploring", "designed", "parked", "superseded"]>>;
|
|
25
|
+
docTier: z.ZodOptional<z.ZodEnum<["S", "M", "L"]>>;
|
|
26
|
+
tags: z.ZodOptional<z.ZodString>;
|
|
27
|
+
docType: z.ZodOptional<z.ZodEnum<["현황", "결정", "이력", "bug"]>>;
|
|
28
|
+
category: z.ZodOptional<z.ZodString>;
|
|
29
|
+
customer: z.ZodOptional<z.ZodString>;
|
|
30
|
+
}, "strip", z.ZodTypeAny, {
|
|
31
|
+
query: string;
|
|
32
|
+
topK: number;
|
|
33
|
+
category?: string | undefined;
|
|
34
|
+
source?: "dev" | "biz" | undefined;
|
|
35
|
+
cluster?: string | undefined;
|
|
36
|
+
fileType?: "biz" | "dev_log" | "decision" | "rule" | "template" | "other" | undefined;
|
|
37
|
+
hasImage?: boolean | undefined;
|
|
38
|
+
docStatus?: "living" | "implemented" | "accepted" | "exploring" | "designed" | "parked" | "superseded" | undefined;
|
|
39
|
+
docTier?: "L" | "M" | "S" | undefined;
|
|
40
|
+
tags?: string | undefined;
|
|
41
|
+
docType?: "현황" | "결정" | "이력" | "bug" | undefined;
|
|
42
|
+
customer?: string | undefined;
|
|
43
|
+
}, {
|
|
44
|
+
query: string;
|
|
45
|
+
category?: string | undefined;
|
|
46
|
+
source?: "dev" | "biz" | undefined;
|
|
47
|
+
cluster?: string | undefined;
|
|
48
|
+
topK?: number | undefined;
|
|
49
|
+
fileType?: "biz" | "dev_log" | "decision" | "rule" | "template" | "other" | undefined;
|
|
50
|
+
hasImage?: boolean | undefined;
|
|
51
|
+
docStatus?: "living" | "implemented" | "accepted" | "exploring" | "designed" | "parked" | "superseded" | undefined;
|
|
52
|
+
docTier?: "L" | "M" | "S" | undefined;
|
|
53
|
+
tags?: string | undefined;
|
|
54
|
+
docType?: "현황" | "결정" | "이력" | "bug" | undefined;
|
|
55
|
+
customer?: string | undefined;
|
|
56
|
+
}>;
|
|
57
|
+
export declare const semanticSearchDriveTool: import("../../../plugin/define.js").Tool<z.ZodObject<{
|
|
58
|
+
query: z.ZodString;
|
|
59
|
+
topK: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
60
|
+
fileType: z.ZodOptional<z.ZodEnum<["dev_log", "decision", "rule", "template", "biz", "other"]>>;
|
|
61
|
+
source: z.ZodOptional<z.ZodEnum<["dev", "biz"]>>;
|
|
62
|
+
cluster: z.ZodOptional<z.ZodString>;
|
|
63
|
+
hasImage: z.ZodOptional<z.ZodBoolean>;
|
|
64
|
+
docStatus: z.ZodOptional<z.ZodEnum<["living", "implemented", "accepted", "exploring", "designed", "parked", "superseded"]>>;
|
|
65
|
+
docTier: z.ZodOptional<z.ZodEnum<["S", "M", "L"]>>;
|
|
66
|
+
tags: z.ZodOptional<z.ZodString>;
|
|
67
|
+
docType: z.ZodOptional<z.ZodEnum<["현황", "결정", "이력", "bug"]>>;
|
|
68
|
+
category: z.ZodOptional<z.ZodString>;
|
|
69
|
+
customer: z.ZodOptional<z.ZodString>;
|
|
70
|
+
}, "strip", z.ZodTypeAny, {
|
|
71
|
+
query: string;
|
|
72
|
+
topK: number;
|
|
73
|
+
category?: string | undefined;
|
|
74
|
+
source?: "dev" | "biz" | undefined;
|
|
75
|
+
cluster?: string | undefined;
|
|
76
|
+
fileType?: "biz" | "dev_log" | "decision" | "rule" | "template" | "other" | undefined;
|
|
77
|
+
hasImage?: boolean | undefined;
|
|
78
|
+
docStatus?: "living" | "implemented" | "accepted" | "exploring" | "designed" | "parked" | "superseded" | undefined;
|
|
79
|
+
docTier?: "L" | "M" | "S" | undefined;
|
|
80
|
+
tags?: string | undefined;
|
|
81
|
+
docType?: "현황" | "결정" | "이력" | "bug" | undefined;
|
|
82
|
+
customer?: string | undefined;
|
|
83
|
+
}, {
|
|
84
|
+
query: string;
|
|
85
|
+
category?: string | undefined;
|
|
86
|
+
source?: "dev" | "biz" | undefined;
|
|
87
|
+
cluster?: string | undefined;
|
|
88
|
+
topK?: number | undefined;
|
|
89
|
+
fileType?: "biz" | "dev_log" | "decision" | "rule" | "template" | "other" | undefined;
|
|
90
|
+
hasImage?: boolean | undefined;
|
|
91
|
+
docStatus?: "living" | "implemented" | "accepted" | "exploring" | "designed" | "parked" | "superseded" | undefined;
|
|
92
|
+
docTier?: "L" | "M" | "S" | undefined;
|
|
93
|
+
tags?: string | undefined;
|
|
94
|
+
docType?: "현황" | "결정" | "이력" | "bug" | undefined;
|
|
95
|
+
customer?: string | undefined;
|
|
96
|
+
}>>;
|
|
97
|
+
export declare function handleSemanticSearchDrive(args: z.infer<typeof inputSchema>): Promise<{
|
|
98
|
+
content: {
|
|
99
|
+
type: "text";
|
|
100
|
+
text: string;
|
|
101
|
+
}[];
|
|
102
|
+
} | {
|
|
103
|
+
content: {
|
|
104
|
+
type: "text";
|
|
105
|
+
text: string;
|
|
106
|
+
}[];
|
|
107
|
+
isError: boolean;
|
|
108
|
+
}>;
|
|
109
|
+
export {};
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* semantic_search_drive — 자연어 질의 → Qdrant vector search → top-K chunks.
|
|
3
|
+
*
|
|
4
|
+
* Pipeline:
|
|
5
|
+
* 1. embed query (OpenAI text-embedding-3-small, 1536d)
|
|
6
|
+
* 2. Qdrant search (Cosine, optional payload filter)
|
|
7
|
+
* 3. payload 를 markdown 으로 포맷 (citation drive link 포함)
|
|
8
|
+
*
|
|
9
|
+
* Latency target (P95):
|
|
10
|
+
* - embed: 200~400ms (OpenAI API)
|
|
11
|
+
* - search: 10~30ms (Qdrant HNSW)
|
|
12
|
+
* - total: 300~500ms
|
|
13
|
+
*
|
|
14
|
+
* Indexing 안 됐으면 `knowledge-mcp drive reindex` 안내.
|
|
15
|
+
*/
|
|
16
|
+
import { z } from 'zod';
|
|
17
|
+
import { defineTool } from '../../../plugin/define.js';
|
|
18
|
+
import { getAuth } from '../../../core/context.js';
|
|
19
|
+
import { allowedDriveFolders, isPathInScope } from '../../../core/scope.js';
|
|
20
|
+
import { isExcludedPath } from '../exclude.js';
|
|
21
|
+
import { embedQuery } from '../embeddings.js';
|
|
22
|
+
import { getQdrantClient, DRIVE_COLLECTION } from '../qdrant.js';
|
|
23
|
+
const FILE_TYPES = ['dev_log', 'decision', 'rule', 'template', 'biz', 'other'];
|
|
24
|
+
const SOURCES = ['dev', 'biz'];
|
|
25
|
+
const DOC_STATUS = ['living', 'implemented', 'accepted', 'exploring', 'designed', 'parked', 'superseded'];
|
|
26
|
+
const DOC_TIER = ['S', 'M', 'L']; // 레거시(폐기) — dev-logs 호환용
|
|
27
|
+
const DOC_TYPES = ['현황', '결정', '이력', 'bug'];
|
|
28
|
+
const KIND_META = {
|
|
29
|
+
current: { label: '현황', boost: 1.1 }, // 개발문서/ — 현재 사실의 1차 근거
|
|
30
|
+
decision: { label: '결정', boost: 1.05 }, // decisions/ — 최신이 현재 정책
|
|
31
|
+
rule: { label: '룰', boost: 1.03 },
|
|
32
|
+
biz: { label: '경영', boost: 1.0 },
|
|
33
|
+
other: { label: '기타', boost: 1.0 },
|
|
34
|
+
log: { label: '이력', boost: 0.97 }, // dev-logs/ — 과거 시점 (현재와 다를 수 있음)
|
|
35
|
+
};
|
|
36
|
+
function classifyKind(p) {
|
|
37
|
+
const path = p.file_path ?? '';
|
|
38
|
+
if (path.startsWith('개발문서/'))
|
|
39
|
+
return 'current';
|
|
40
|
+
if (path.startsWith('decisions/'))
|
|
41
|
+
return 'decision';
|
|
42
|
+
if (path.startsWith('dev-logs/'))
|
|
43
|
+
return 'log';
|
|
44
|
+
if (p.source === 'biz')
|
|
45
|
+
return 'biz';
|
|
46
|
+
if (path.includes('_rules') || path.includes('룰베이스'))
|
|
47
|
+
return 'rule';
|
|
48
|
+
return 'other';
|
|
49
|
+
}
|
|
50
|
+
const DESCRIPTION = 'Semantic (vector RAG) search over your indexed Drive content. ' +
|
|
51
|
+
'자연어 질의로 관련 청크 top-K 반환. ' +
|
|
52
|
+
'source 로 범위 한정: source="dev"(개발 기록) / source="biz"(경영·고객사). **비개발(고객사·경영·전략 등) 질문이면 source="biz" 로 좁혀라.** ' +
|
|
53
|
+
'키워드/파일명 검색 (search_drive) 으로 답이 안 나올 때, 또는 "X 가 어떻게 동작하는지", "Y 결정의 배경", 특정 고객사·전략 내용 같은 의미 질의 시 사용. ' +
|
|
54
|
+
'결과에 score · file_path · heading · File ID · Drive link · 본문 청크 포함. ' +
|
|
55
|
+
'**2단계 검색**: 청크만으로 맥락이 부족하면 응답의 File ID 로 read_drive_file 을 호출해 원문 전체를 읽어라.';
|
|
56
|
+
const inputSchema = z.object({
|
|
57
|
+
query: z
|
|
58
|
+
.string()
|
|
59
|
+
.min(1)
|
|
60
|
+
.max(500)
|
|
61
|
+
.describe('자연어 검색 쿼리 (한국어/영어). 예: "JSON-LD planner 가 schema type 어떻게 분류하지?"'),
|
|
62
|
+
topK: z.number().int().min(1).max(20).optional().default(5).describe('반환할 청크 수 (1~20, default 5)'),
|
|
63
|
+
fileType: z.enum(FILE_TYPES).optional().describe('파일 종류 filter (선택): dev_log / decision / rule / template / biz / other'),
|
|
64
|
+
source: z.enum(SOURCES).optional().describe('Source filter (optional): dev (structured docs) / biz (general documents)'),
|
|
65
|
+
cluster: z.string().optional().describe('테마 cluster filter (선택). dev: "03-jsonld-pipeline" 등 / biz: "01_고객사" 등'),
|
|
66
|
+
hasImage: z.boolean().optional().describe('이미지 포함 청크만 (선택). 화면 캡처·다이어그램 있는 문서 찾을 때.'),
|
|
67
|
+
docStatus: z
|
|
68
|
+
.enum(DOC_STATUS)
|
|
69
|
+
.optional()
|
|
70
|
+
.describe('문서 상태 filter (선택): living / implemented / accepted / exploring / parked / superseded'),
|
|
71
|
+
docTier: z.enum(DOC_TIER).optional().describe('(레거시) 문서 tier filter: S / M / L — 폐기됨, dev-logs 호환용'),
|
|
72
|
+
tags: z
|
|
73
|
+
.string()
|
|
74
|
+
.optional()
|
|
75
|
+
.describe('태그 filter (선택). dev=frontmatter tags(예 "geo-audit","supabase") / biz=경로·파일명 파생 태그'),
|
|
76
|
+
docType: z.enum(DOC_TYPES).optional().describe('문서 모드 filter (선택): 현황 / 결정 / 이력 / bug'),
|
|
77
|
+
category: z.string().optional().describe('biz 경영문서 분류 filter (선택). 예: "고객사", "IR_피칭덱", "세일즈"'),
|
|
78
|
+
customer: z.string().optional().describe('biz 고객사 filter (선택). 예: "Acme", "Globex"'),
|
|
79
|
+
});
|
|
80
|
+
export const semanticSearchDriveTool = defineTool({
|
|
81
|
+
name: 'semantic_search_drive',
|
|
82
|
+
description: DESCRIPTION,
|
|
83
|
+
input: inputSchema,
|
|
84
|
+
annotations: { readOnlyHint: true },
|
|
85
|
+
run: (args) => handleSemanticSearchDrive(args),
|
|
86
|
+
});
|
|
87
|
+
export async function handleSemanticSearchDrive(args) {
|
|
88
|
+
// 외부 의존(OpenAI 임베딩·Qdrant) 실패를 도구 특화 graceful 에러로 — 예전엔 [fatal] 로만 떴다.
|
|
89
|
+
// 입력은 registry 가 이미 검증했다.
|
|
90
|
+
try {
|
|
91
|
+
return await _handleSemanticSearchDrive(args);
|
|
92
|
+
}
|
|
93
|
+
catch (e) {
|
|
94
|
+
return {
|
|
95
|
+
content: [
|
|
96
|
+
{
|
|
97
|
+
type: 'text',
|
|
98
|
+
text: `[error] 의미 검색 백엔드 일시 오류 — 잠시 후 재시도하거나 search_drive 로 대체하세요. (${e instanceof Error ? e.message : String(e)})`,
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
isError: true,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async function _handleSemanticSearchDrive(args) {
|
|
106
|
+
const auth = getAuth();
|
|
107
|
+
const { query, topK, fileType, source, cluster, hasImage, docStatus, docTier, tags, docType, category, customer } = args;
|
|
108
|
+
// 1. Embed query (RETRIEVAL_QUERY taskType — asymmetric retrieval)
|
|
109
|
+
const queryVector = await embedQuery(query);
|
|
110
|
+
// 2. Qdrant filter (optional)
|
|
111
|
+
const must = [];
|
|
112
|
+
if (fileType)
|
|
113
|
+
must.push({ key: 'file_type', match: { value: fileType } });
|
|
114
|
+
if (source)
|
|
115
|
+
must.push({ key: 'source', match: { value: source } });
|
|
116
|
+
if (cluster)
|
|
117
|
+
must.push({ key: 'cluster', match: { value: cluster } });
|
|
118
|
+
if (hasImage !== undefined)
|
|
119
|
+
must.push({ key: 'has_image', match: { value: hasImage } });
|
|
120
|
+
if (docStatus)
|
|
121
|
+
must.push({ key: 'doc_status', match: { value: docStatus } });
|
|
122
|
+
if (docTier)
|
|
123
|
+
must.push({ key: 'doc_tier', match: { value: docTier } });
|
|
124
|
+
if (tags)
|
|
125
|
+
must.push({ key: 'doc_tags', match: { value: tags } });
|
|
126
|
+
if (docType)
|
|
127
|
+
must.push({ key: 'doc_type', match: { value: docType } });
|
|
128
|
+
if (category)
|
|
129
|
+
must.push({ key: 'doc_category', match: { value: category } });
|
|
130
|
+
if (customer)
|
|
131
|
+
must.push({ key: 'doc_customer', match: { value: customer } });
|
|
132
|
+
// 3. Search — 현황 우선 rerank 여지 위해 topK 보다 넓게 검색 (현황이 topK 밖으로 밀리는 것 방지)
|
|
133
|
+
const client = await getQdrantClient();
|
|
134
|
+
const searchLimit = Math.min(50, Math.max(topK * 3, 18));
|
|
135
|
+
const results = await client.search(DRIVE_COLLECTION, {
|
|
136
|
+
vector: queryVector,
|
|
137
|
+
limit: searchLimit,
|
|
138
|
+
with_payload: true,
|
|
139
|
+
filter: must.length > 0 ? { must } : undefined,
|
|
140
|
+
});
|
|
141
|
+
if (results.length === 0) {
|
|
142
|
+
return {
|
|
143
|
+
content: [
|
|
144
|
+
{
|
|
145
|
+
type: 'text',
|
|
146
|
+
text: `검색 결과 없음. query="${query}"\n\n` +
|
|
147
|
+
`가능한 원인:\n` +
|
|
148
|
+
`- Drive 가 아직 indexing 안 됨 → 관리자에게 \`knowledge-mcp drive reindex\` 실행 요청\n` +
|
|
149
|
+
`- filter 가 너무 좁힘 (source="${source ?? '없음'}", fileType="${fileType ?? '없음'}", cluster="${cluster ?? '없음'}")` +
|
|
150
|
+
(fileType && source &&
|
|
151
|
+
((source === 'dev' && fileType === 'biz') ||
|
|
152
|
+
(source === 'biz' && fileType !== 'biz' && fileType !== 'other'))
|
|
153
|
+
? ` ⚠️ **source 와 fileType 이 모순** — biz fileType 은 source=biz 에만, dev_log/decision/rule/template 은 source=dev 에만 존재. 둘 중 하나만 쓰세요.`
|
|
154
|
+
: '') +
|
|
155
|
+
`\n` +
|
|
156
|
+
`- 의미 매칭이 약함 → 다른 단어로 재시도`,
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
// 3b. 현황 우선 rerank — kind boost + superseded/parked 강등
|
|
162
|
+
const reranked = results
|
|
163
|
+
.map((r) => {
|
|
164
|
+
const p = r.payload;
|
|
165
|
+
const kind = classifyKind(p);
|
|
166
|
+
let boost = KIND_META[kind].boost;
|
|
167
|
+
if (p.doc_status === 'superseded')
|
|
168
|
+
boost *= 0.8; // 대체된 문서 강등
|
|
169
|
+
else if (p.doc_status === 'parked')
|
|
170
|
+
boost *= 0.92;
|
|
171
|
+
return { r, p, kind, adj: r.score * boost };
|
|
172
|
+
})
|
|
173
|
+
.sort((a, b) => b.adj - a.adj);
|
|
174
|
+
// 3c. 제외 폴더 재확인 + 직원별 Drive 폴더 scope 필터 (admin·미설정 = 전체) 적용 후 topK 선별.
|
|
175
|
+
// 제외 재확인: excludeFolders 를 나중에 추가했거나 아직 sync 가 돌지 않아 남은 옛 청크를 응답에서 뺀다.
|
|
176
|
+
const folderScope = allowedDriveFolders(auth);
|
|
177
|
+
const ranked = reranked
|
|
178
|
+
.filter((x) => !isExcludedPath(x.p.file_path ?? ''))
|
|
179
|
+
.filter((x) => !folderScope || isPathInScope(x.p.file_path ?? '', folderScope))
|
|
180
|
+
.slice(0, topK);
|
|
181
|
+
// 4. Markdown 포맷 (사람·LLM 둘 다 읽기 좋음)
|
|
182
|
+
const lines = [];
|
|
183
|
+
lines.push(`# 의미 검색 결과 — "${query}"`);
|
|
184
|
+
lines.push(`${ranked.length}개 chunk (${results.length}개 중 현황 우선 정렬) · top-${topK} 요청`);
|
|
185
|
+
lines.push(`> **현황 우선 정렬됨.** \`[현황]\`=현재 사실(개발문서) · \`[이력]\`=과거 시점(dev-logs, 현재와 다를 수 있음) · \`[결정]\`=정책. ` +
|
|
186
|
+
`**사실·수치는 [현황]/최신 날짜를 신뢰**하고, [이력]과 충돌하면 [현황]을 현재 값으로 채택하라.`);
|
|
187
|
+
if (fileType || cluster) {
|
|
188
|
+
lines.push(`Filter: ${[fileType && `fileType=${fileType}`, cluster && `cluster=${cluster}`].filter(Boolean).join(', ')}`);
|
|
189
|
+
}
|
|
190
|
+
lines.push('');
|
|
191
|
+
for (let i = 0; i < ranked.length; i++) {
|
|
192
|
+
const { r, p, kind, adj } = ranked[i];
|
|
193
|
+
const meta = KIND_META[kind];
|
|
194
|
+
const driveLink = `https://drive.google.com/file/d/${p.file_id}/view`;
|
|
195
|
+
const dateStr = p.doc_date ? ` · ${p.doc_date}` : '';
|
|
196
|
+
const statusStr = p.doc_status === 'superseded' ? ' · ⚠️대체됨' : p.doc_status === 'parked' ? ' · 보류' : '';
|
|
197
|
+
lines.push(`---`);
|
|
198
|
+
lines.push(`### ${i + 1}. [${meta.label}${dateStr}${statusStr}] ${p.file_name}`);
|
|
199
|
+
const chunkPos = typeof p.chunk_index === 'number' && typeof p.chunk_count === 'number' && p.chunk_count > 1
|
|
200
|
+
? ` · **청크:** ${p.chunk_index + 1}/${p.chunk_count}(문서 일부 — 수치·전체 맥락은 read_drive_file)`
|
|
201
|
+
: '';
|
|
202
|
+
// 표시 점수 = 정렬 기준(adj). 현황/이력 boost 로 raw 와 달라졌으면 raw 도 병기(표시-정렬 불일치 혼란 방지).
|
|
203
|
+
lines.push(`**Score:** ${adj.toFixed(3)}` +
|
|
204
|
+
(Math.abs(adj - r.score) > 0.001 ? ` (raw ${r.score.toFixed(3)} · 현황/이력 boost 반영)` : '') +
|
|
205
|
+
` · **종류:** ${meta.label} · **Type:** ${p.file_type}` +
|
|
206
|
+
(p.cluster ? ` · **Cluster:** ${p.cluster}` : '') +
|
|
207
|
+
chunkPos);
|
|
208
|
+
lines.push(`**Path:** \`${p.file_path}\``);
|
|
209
|
+
lines.push(`**Heading:** ${p.heading}`);
|
|
210
|
+
lines.push(`**File ID:** \`${p.file_id}\` — 전문 필요 시 \`read_drive_file\` 에 사용`);
|
|
211
|
+
lines.push(`**Drive:** [열기](${driveLink})`);
|
|
212
|
+
if (p.image_urls && p.image_urls.length > 0) {
|
|
213
|
+
lines.push(`**Images:** ${p.image_urls.length}개 — ${p.image_urls.join(' · ')}`);
|
|
214
|
+
}
|
|
215
|
+
lines.push('');
|
|
216
|
+
lines.push(p.content);
|
|
217
|
+
lines.push('');
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
content: [
|
|
221
|
+
{
|
|
222
|
+
type: 'text',
|
|
223
|
+
text: lines.join('\n'),
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=semantic_search_drive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic_search_drive.js","sourceRoot":"","sources":["../../../../src/plugins/drive/tools/semantic_search_drive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const githubPlugin: import("../../plugin/define.js").Plugin;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub plugin — repo_tree (local) plus GitHub's remote MCP server through the gateway, read-only.
|
|
3
|
+
*
|
|
4
|
+
* GITHUB_TOKEN (or GITHUB_PAT) fine-grained token with Contents: read (Metadata: read)
|
|
5
|
+
* GITHUB_MCP_INSIDERS=true optional, opts into GitHub MCP insiders tools
|
|
6
|
+
* Remote tools appear as github_<name>; only read verbs (get_, list_, search_ ...) are exposed.
|
|
7
|
+
*/
|
|
8
|
+
import { definePlugin } from '../../plugin/define.js';
|
|
9
|
+
import { repoTreeTool } from './repo_tree.js';
|
|
10
|
+
const token = () => process.env.GITHUB_TOKEN || process.env.GITHUB_PAT;
|
|
11
|
+
export const githubPlugin = definePlugin({
|
|
12
|
+
id: 'github',
|
|
13
|
+
description: 'GitHub repo tree + remote GitHub MCP (read-only)',
|
|
14
|
+
enabled: () => !!token()?.trim() || 'set GITHUB_TOKEN (or GITHUB_PAT)',
|
|
15
|
+
tools: [repoTreeTool],
|
|
16
|
+
upstreams: () => [
|
|
17
|
+
{
|
|
18
|
+
name: 'github',
|
|
19
|
+
url: 'https://api.githubcopilot.com/mcp/',
|
|
20
|
+
prefix: 'github_',
|
|
21
|
+
token,
|
|
22
|
+
headers: process.env.GITHUB_MCP_INSIDERS === 'true' ? { 'X-MCP-Insiders': 'true' } : undefined,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
instructions: 'GitHub: code structure → repo_tree first, then github_get_file_contents for the files you need.',
|
|
26
|
+
});
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/github/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;AAEvE,MAAM,CAAC,MAAM,YAAY,GAAG,YAAY,CAAC;IACvC,EAAE,EAAE,QAAQ;IACZ,WAAW,EAAE,kDAAkD;IAC/D,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,kCAAkC;IACtE,KAAK,EAAE,CAAC,YAAY,CAAC;IACrB,SAAS,EAAE,GAAG,EAAE,CAAC;QACf;YACE,IAAI,EAAE,QAAQ;YACd,GAAG,EAAE,oCAAoC;YACzC,MAAM,EAAE,SAAS;YACjB,KAAK;YACL,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS;SAC/F;KACF;IACD,YAAY,EAAE,iGAAiG;CAChH,CAAC,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* repo_tree(owner, repo, ref?, filterExt?) — GitHub repo 전체 파일 트리(경로 목록).
|
|
3
|
+
*
|
|
4
|
+
* search_code 는 private repo 를 인덱싱하지 않으므로, 사내 코드 질문은
|
|
5
|
+
* "이 트리로 구조 파악 → 필요 파일만 github_get_file_contents 로 조회" 패턴을 쓴다.
|
|
6
|
+
* git/trees?recursive=1 로 한 번에 전체 경로를 받고, node_modules·dist 등 아티팩트는 제외.
|
|
7
|
+
*
|
|
8
|
+
* 토큰: GITHUB_TOKEN (upstream github 과 동일 키). Contents read 권한이면 private 도 트리 조회 가능.
|
|
9
|
+
* 이름에 github_ prefix 를 안 쓰는 이유: github_ 는 원격 GitHub MCP 도구의 prefix 라 이름이 겹칠 수 있다(겹치면 로컬이 이기고 원격 도구가 가려진다).
|
|
10
|
+
*/
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
declare const inputSchema: z.ZodObject<{
|
|
13
|
+
owner: z.ZodString;
|
|
14
|
+
repo: z.ZodString;
|
|
15
|
+
ref: z.ZodOptional<z.ZodString>;
|
|
16
|
+
filterExt: z.ZodOptional<z.ZodString>;
|
|
17
|
+
}, "strip", z.ZodTypeAny, {
|
|
18
|
+
owner: string;
|
|
19
|
+
repo: string;
|
|
20
|
+
ref?: string | undefined;
|
|
21
|
+
filterExt?: string | undefined;
|
|
22
|
+
}, {
|
|
23
|
+
owner: string;
|
|
24
|
+
repo: string;
|
|
25
|
+
ref?: string | undefined;
|
|
26
|
+
filterExt?: string | undefined;
|
|
27
|
+
}>;
|
|
28
|
+
export declare const repoTreeTool: import("../../plugin/define.js").Tool<z.ZodObject<{
|
|
29
|
+
owner: z.ZodString;
|
|
30
|
+
repo: z.ZodString;
|
|
31
|
+
ref: z.ZodOptional<z.ZodString>;
|
|
32
|
+
filterExt: z.ZodOptional<z.ZodString>;
|
|
33
|
+
}, "strip", z.ZodTypeAny, {
|
|
34
|
+
owner: string;
|
|
35
|
+
repo: string;
|
|
36
|
+
ref?: string | undefined;
|
|
37
|
+
filterExt?: string | undefined;
|
|
38
|
+
}, {
|
|
39
|
+
owner: string;
|
|
40
|
+
repo: string;
|
|
41
|
+
ref?: string | undefined;
|
|
42
|
+
filterExt?: string | undefined;
|
|
43
|
+
}>>;
|
|
44
|
+
export declare function handleRepoTree(args: z.infer<typeof inputSchema>): Promise<{
|
|
45
|
+
content: {
|
|
46
|
+
type: "text";
|
|
47
|
+
text: string;
|
|
48
|
+
}[];
|
|
49
|
+
isError: boolean;
|
|
50
|
+
} | {
|
|
51
|
+
content: {
|
|
52
|
+
type: "text";
|
|
53
|
+
text: string;
|
|
54
|
+
}[];
|
|
55
|
+
isError?: undefined;
|
|
56
|
+
}>;
|
|
57
|
+
export {};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* repo_tree(owner, repo, ref?, filterExt?) — GitHub repo 전체 파일 트리(경로 목록).
|
|
3
|
+
*
|
|
4
|
+
* search_code 는 private repo 를 인덱싱하지 않으므로, 사내 코드 질문은
|
|
5
|
+
* "이 트리로 구조 파악 → 필요 파일만 github_get_file_contents 로 조회" 패턴을 쓴다.
|
|
6
|
+
* git/trees?recursive=1 로 한 번에 전체 경로를 받고, node_modules·dist 등 아티팩트는 제외.
|
|
7
|
+
*
|
|
8
|
+
* 토큰: GITHUB_TOKEN (upstream github 과 동일 키). Contents read 권한이면 private 도 트리 조회 가능.
|
|
9
|
+
* 이름에 github_ prefix 를 안 쓰는 이유: github_ 는 원격 GitHub MCP 도구의 prefix 라 이름이 겹칠 수 있다(겹치면 로컬이 이기고 원격 도구가 가려진다).
|
|
10
|
+
*/
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
import { defineTool } from '../../plugin/define.js';
|
|
13
|
+
import { getAuth } from '../../core/context.js';
|
|
14
|
+
const GITHUB_API = 'https://api.github.com';
|
|
15
|
+
const MAX_FILES = 600;
|
|
16
|
+
const GH_TIMEOUT_MS = 20_000;
|
|
17
|
+
/** AbortController timeout 을 건 fetch (hang 방지). */
|
|
18
|
+
async function ghFetch(url, headers) {
|
|
19
|
+
const ctrl = new AbortController();
|
|
20
|
+
const timer = setTimeout(() => ctrl.abort(), GH_TIMEOUT_MS);
|
|
21
|
+
try {
|
|
22
|
+
return await fetch(url, { headers, signal: ctrl.signal });
|
|
23
|
+
}
|
|
24
|
+
catch (e) {
|
|
25
|
+
if (e instanceof Error && e.name === 'AbortError') {
|
|
26
|
+
throw new Error(`GitHub API timeout ${GH_TIMEOUT_MS}ms (${url})`);
|
|
27
|
+
}
|
|
28
|
+
throw e;
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
clearTimeout(timer);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const inputSchema = z.object({
|
|
35
|
+
owner: z.string().min(1).describe('e.g. my-org'),
|
|
36
|
+
repo: z.string().min(1).describe('e.g. my-repo'),
|
|
37
|
+
ref: z.string().optional().describe('브랜치/SHA (생략 시 default branch)'),
|
|
38
|
+
filterExt: z.string().optional().describe('확장자 필터 (쉼표구분, 예: "ts,tsx"). 생략 시 전체'),
|
|
39
|
+
});
|
|
40
|
+
export const repoTreeTool = defineTool({
|
|
41
|
+
name: 'repo_tree',
|
|
42
|
+
description: 'GitHub repo 의 전체 파일 트리(경로 목록)를 반환. 사내 코드 질문 시 가장 먼저 호출해 구조를 파악한 뒤, ' +
|
|
43
|
+
'필요한 파일만 github_get_file_contents(owner, repo, path) 로 읽어 답하라. ' +
|
|
44
|
+
'Works with private repos too (search_code cannot index private repos, so use this tree+get combo). ' +
|
|
45
|
+
'filterExt 로 확장자 한정 가능(예: "ts,tsx,py").',
|
|
46
|
+
input: inputSchema,
|
|
47
|
+
annotations: { readOnlyHint: true },
|
|
48
|
+
run: (args) => handleRepoTree(args),
|
|
49
|
+
});
|
|
50
|
+
function ghHeaders() {
|
|
51
|
+
const token = process.env.GITHUB_TOKEN || process.env.GITHUB_PAT;
|
|
52
|
+
if (!token)
|
|
53
|
+
throw new Error('[repo_tree] GITHUB_TOKEN / GITHUB_PAT 미설정');
|
|
54
|
+
return { Authorization: `Bearer ${token}`, Accept: 'application/vnd.github+json' };
|
|
55
|
+
}
|
|
56
|
+
const ARTIFACT_RE = /(^|\/)(node_modules|dist|build|\.next|\.nuxt|coverage|\.git|__pycache__|\.venv|venv)\//;
|
|
57
|
+
// GitHub 이름 규칙(영숫자, '.', '_', '-'). 경로 조작('..', '/')으로 다른 API 경로를 부르지 못하게 막는다.
|
|
58
|
+
const GH_NAME_RE = /^(?!\.\.?$)[A-Za-z0-9._-]+$/;
|
|
59
|
+
export async function handleRepoTree(args) {
|
|
60
|
+
getAuth();
|
|
61
|
+
const { owner, repo, ref, filterExt } = args;
|
|
62
|
+
if (!GH_NAME_RE.test(owner) || !GH_NAME_RE.test(repo)) {
|
|
63
|
+
return {
|
|
64
|
+
content: [{ type: 'text', text: '[invalid_input] owner/repo 이름 형식이 올바르지 않습니다.' }],
|
|
65
|
+
isError: true,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const headers = ghHeaders();
|
|
69
|
+
try {
|
|
70
|
+
// default branch resolve
|
|
71
|
+
let sha = ref;
|
|
72
|
+
if (!sha) {
|
|
73
|
+
const r = await ghFetch(`${GITHUB_API}/repos/${owner}/${repo}`, headers);
|
|
74
|
+
if (!r.ok) {
|
|
75
|
+
return {
|
|
76
|
+
content: [{ type: 'text', text: `[error] repo ${owner}/${repo} 접근 실패 (HTTP ${r.status}). 권한/이름 확인.` }],
|
|
77
|
+
isError: true,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
sha = (await r.json()).default_branch ?? 'main';
|
|
81
|
+
}
|
|
82
|
+
const tr = await ghFetch(`${GITHUB_API}/repos/${owner}/${repo}/git/trees/${encodeURIComponent(sha)}?recursive=1`, headers);
|
|
83
|
+
if (!tr.ok) {
|
|
84
|
+
return {
|
|
85
|
+
content: [{ type: 'text', text: `[error] tree 조회 실패 (HTTP ${tr.status}, ref=${sha})` }],
|
|
86
|
+
isError: true,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const data = (await tr.json());
|
|
90
|
+
let files = (data.tree ?? [])
|
|
91
|
+
.filter((t) => t.type === 'blob')
|
|
92
|
+
.map((t) => t.path)
|
|
93
|
+
.filter((p) => !ARTIFACT_RE.test(p));
|
|
94
|
+
if (filterExt) {
|
|
95
|
+
const exts = filterExt.split(',').map((e) => e.trim().replace(/^\./, '')).filter(Boolean);
|
|
96
|
+
if (exts.length)
|
|
97
|
+
files = files.filter((p) => exts.some((e) => p.endsWith('.' + e)));
|
|
98
|
+
}
|
|
99
|
+
const truncated = data.truncated || files.length > MAX_FILES;
|
|
100
|
+
const shown = files.slice(0, MAX_FILES);
|
|
101
|
+
return {
|
|
102
|
+
content: [
|
|
103
|
+
{
|
|
104
|
+
type: 'text',
|
|
105
|
+
text: JSON.stringify({
|
|
106
|
+
repo: `${owner}/${repo}`,
|
|
107
|
+
ref: sha,
|
|
108
|
+
total_files: files.length,
|
|
109
|
+
shown: shown.length,
|
|
110
|
+
truncated,
|
|
111
|
+
note: '필요 파일은 github_get_file_contents(owner, repo, path, ref) 로 조회',
|
|
112
|
+
files: shown,
|
|
113
|
+
}, null, 2),
|
|
114
|
+
},
|
|
115
|
+
],
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
catch (e) {
|
|
119
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
120
|
+
return { content: [{ type: 'text', text: `[error] ${msg}` }], isError: true };
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=repo_tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo_tree.js","sourceRoot":"","sources":["../../../src/plugins/github/repo_tree.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in plugins. Each one turns itself on when its credentials are in env, so listing all of them
|
|
3
|
+
* costs nothing: `knowledge-mcp doctor` shows which are on and what each one is missing.
|
|
4
|
+
*/
|
|
5
|
+
import type { Plugin } from '../plugin/define.js';
|
|
6
|
+
import { drivePlugin } from './drive/index.js';
|
|
7
|
+
import { slackPlugin } from './slack/index.js';
|
|
8
|
+
import { githubPlugin } from './github/index.js';
|
|
9
|
+
import { railwayPlugin } from './railway/index.js';
|
|
10
|
+
export { drivePlugin, slackPlugin, githubPlugin, railwayPlugin };
|
|
11
|
+
export declare const builtinPlugins: Plugin[];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { drivePlugin } from './drive/index.js';
|
|
2
|
+
import { slackPlugin } from './slack/index.js';
|
|
3
|
+
import { githubPlugin } from './github/index.js';
|
|
4
|
+
import { railwayPlugin } from './railway/index.js';
|
|
5
|
+
export { drivePlugin, slackPlugin, githubPlugin, railwayPlugin };
|
|
6
|
+
export const builtinPlugins = [drivePlugin, slackPlugin, githubPlugin, railwayPlugin];
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plugins/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;AAEjE,MAAM,CAAC,MAAM,cAAc,GAAa,CAAC,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const railwayPlugin: import("../../plugin/define.js").Plugin;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Railway plugin — services, deployments and logs over Railway's GraphQL API (logs are masked).
|
|
3
|
+
*
|
|
4
|
+
* RAILWAY_TOKEN team/account token for every project (a project token sees one project)
|
|
5
|
+
* RAILWAY_MCP_URL + RAILWAY_MCP_TOKEN optional remote Railway MCP through the gateway (railway_<name>)
|
|
6
|
+
* When a remote tool has the same name as a local one, the local tool wins.
|
|
7
|
+
*/
|
|
8
|
+
import { definePlugin } from '../../plugin/define.js';
|
|
9
|
+
import { railwayServicesTool, railwayDeploymentsTool, railwayLogsTool } from './tools.js';
|
|
10
|
+
const token = () => process.env.RAILWAY_TOKEN || process.env.RAILWAY_MCP_TOKEN;
|
|
11
|
+
export const railwayPlugin = definePlugin({
|
|
12
|
+
id: 'railway',
|
|
13
|
+
description: 'Railway services, deployments and logs',
|
|
14
|
+
enabled: () => !!token()?.trim() || 'set RAILWAY_TOKEN',
|
|
15
|
+
tools: [railwayServicesTool, railwayDeploymentsTool, railwayLogsTool],
|
|
16
|
+
upstreams: () => process.env.RAILWAY_MCP_URL && process.env.RAILWAY_MCP_TOKEN
|
|
17
|
+
? [{ name: 'railway', url: process.env.RAILWAY_MCP_URL, prefix: 'railway_', token: process.env.RAILWAY_MCP_TOKEN }]
|
|
18
|
+
: [],
|
|
19
|
+
instructions: 'Railway: railway_services → railway_deployments → railway_logs.',
|
|
20
|
+
});
|
|
21
|
+
//# sourceMappingURL=index.js.map
|