ragalgo-mcp-server 1.0.6 → 1.0.7
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/dist/utils/api.js +59 -27
- package/package.json +1 -1
- package/server.json +2 -2
package/dist/utils/api.js
CHANGED
|
@@ -2,6 +2,45 @@
|
|
|
2
2
|
* RagAlgo API 유틸리티
|
|
3
3
|
* Supabase Edge Functions 호출
|
|
4
4
|
*/
|
|
5
|
+
const CACHE_TTL_MS = 5 * 60 * 1000; // 5분
|
|
6
|
+
const cache = new Map();
|
|
7
|
+
function getCacheKey(endpoint, params) {
|
|
8
|
+
const sortedParams = params
|
|
9
|
+
? Object.entries(params)
|
|
10
|
+
.filter(([, v]) => v !== undefined)
|
|
11
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
12
|
+
.map(([k, v]) => `${k}=${v}`)
|
|
13
|
+
.join('&')
|
|
14
|
+
: '';
|
|
15
|
+
return `${endpoint}?${sortedParams}`;
|
|
16
|
+
}
|
|
17
|
+
function getFromCache(key) {
|
|
18
|
+
const entry = cache.get(key);
|
|
19
|
+
if (!entry)
|
|
20
|
+
return null;
|
|
21
|
+
const now = Date.now();
|
|
22
|
+
if (now - entry.timestamp > CACHE_TTL_MS) {
|
|
23
|
+
cache.delete(key);
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
return entry.data;
|
|
27
|
+
}
|
|
28
|
+
function setCache(key, data) {
|
|
29
|
+
// 캐시 크기 제한 (최대 100개)
|
|
30
|
+
if (cache.size > 100) {
|
|
31
|
+
const oldestKey = cache.keys().next().value;
|
|
32
|
+
if (oldestKey)
|
|
33
|
+
cache.delete(oldestKey);
|
|
34
|
+
}
|
|
35
|
+
cache.set(key, {
|
|
36
|
+
data,
|
|
37
|
+
timestamp: Date.now()
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
// 캐시 통계 (디버그용)
|
|
41
|
+
let cacheHits = 0;
|
|
42
|
+
let cacheMisses = 0;
|
|
43
|
+
// ============================================================================
|
|
5
44
|
// [CHANGED] Dynamic URL Support
|
|
6
45
|
// If SUPABASE_URL is injected (from Desktop .env), use it. Otherwise fallback to hardcoded (Public default).
|
|
7
46
|
const DEFAULT_URL = 'https://xunrsikkybgxkybjzrgz.supabase.co/functions/v1';
|
|
@@ -24,27 +63,19 @@ const getKeys = () => {
|
|
|
24
63
|
const fallbackAnon = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inh1bnJzaWtreWJneGt5Ymp6cmd6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjQ0NTExNTgsImV4cCI6MjA4MDAyNzE1OH0.SsXri828-Rf0gHlu4Bls-pewhfMNNII4mbiuLnc9ACs";
|
|
25
64
|
return { apiKey, anonKey: anonKey || fallbackAnon };
|
|
26
65
|
};
|
|
27
|
-
// API 호출 기본 함수
|
|
66
|
+
// API 호출 기본 함수 (5분 캐시 적용)
|
|
28
67
|
export async function callApi(endpoint, params) {
|
|
68
|
+
// [CACHE] 캐시 확인
|
|
69
|
+
const cacheKey = getCacheKey(endpoint, params);
|
|
70
|
+
const cachedData = getFromCache(cacheKey);
|
|
71
|
+
if (cachedData !== null) {
|
|
72
|
+
cacheHits++;
|
|
73
|
+
console.error(`[CACHE HIT] ${endpoint} (hits: ${cacheHits}, misses: ${cacheMisses})`);
|
|
74
|
+
return cachedData;
|
|
75
|
+
}
|
|
76
|
+
cacheMisses++;
|
|
77
|
+
console.error(`[CACHE MISS] ${endpoint} (hits: ${cacheHits}, misses: ${cacheMisses})`);
|
|
29
78
|
const { apiKey, anonKey } = getKeys();
|
|
30
|
-
// [DEBUG] Log token details to stderr
|
|
31
|
-
// console.error(`[API] User Token Len: ${apiKey?.length}, Anon Key Len: ${anonKey?.length}`);
|
|
32
|
-
// 쿼리 파라미터 생성
|
|
33
|
-
// Use constructed SUPABASE_URL which already includes /functions/v1/ or similar base
|
|
34
|
-
// But wait, the DEFAULT_URL includes /functions/v1
|
|
35
|
-
// The previous code did: new URL(`${SUPABASE_URL}/${endpoint}`);
|
|
36
|
-
// If process.env.SUPABASE_URL is just the base (e.g. https://...co), we need to append /functions/v1
|
|
37
|
-
// Adjusted Logic above:
|
|
38
|
-
// If process.env.SUPABASE_URL is provided, we assume it is the PROJECT URL (not including /functions/v1).
|
|
39
|
-
// So we append /functions/v1.
|
|
40
|
-
// Ensure we don't duplicate slashes
|
|
41
|
-
const baseUrl = SUPABASE_URL.endsWith('/functions/v1') ? SUPABASE_URL : `${SUPABASE_URL}/functions/v1`;
|
|
42
|
-
// Actually, let's simplify.
|
|
43
|
-
// The previous code had `const SUPABASE_URL = '.../functions/v1';`
|
|
44
|
-
// And usage: `new URL(`${SUPABASE_URL}/${endpoint}`);` which results in `.../functions/v1/snapshots`
|
|
45
|
-
// My replacement above:
|
|
46
|
-
// const SUPABASE_URL = ... (process.env.SUPABASE_URL ? .../functions/v1 :)
|
|
47
|
-
// So usage here:
|
|
48
79
|
const url = new URL(`${SUPABASE_URL}/${endpoint}`);
|
|
49
80
|
if (params) {
|
|
50
81
|
Object.entries(params).forEach(([key, value]) => {
|
|
@@ -54,9 +85,9 @@ export async function callApi(endpoint, params) {
|
|
|
54
85
|
});
|
|
55
86
|
}
|
|
56
87
|
const headers = {
|
|
57
|
-
'Authorization': `Bearer ${anonKey.trim()}`,
|
|
88
|
+
'Authorization': `Bearer ${anonKey.trim()}`,
|
|
58
89
|
'apikey': anonKey.trim(),
|
|
59
|
-
'x-api-key': apiKey.trim(),
|
|
90
|
+
'x-api-key': apiKey.trim(),
|
|
60
91
|
'Content-Type': 'application/json',
|
|
61
92
|
};
|
|
62
93
|
const response = await fetch(url.toString(), {
|
|
@@ -71,18 +102,19 @@ export async function callApi(endpoint, params) {
|
|
|
71
102
|
}
|
|
72
103
|
throw new Error(`API 호출 실패: ${response.status} - ${error} | ${debugInfo}`);
|
|
73
104
|
}
|
|
74
|
-
|
|
105
|
+
const data = await response.json();
|
|
106
|
+
// [CACHE] 성공 시 캐시에 저장
|
|
107
|
+
setCache(cacheKey, data);
|
|
108
|
+
return data;
|
|
75
109
|
}
|
|
76
|
-
// POST API 호출
|
|
110
|
+
// POST API 호출 (POST는 캐시하지 않음 - 데이터 변경 가능성)
|
|
77
111
|
export async function callApiPost(endpoint, body) {
|
|
78
112
|
const { apiKey, anonKey } = getKeys();
|
|
79
113
|
const url = `${SUPABASE_URL}/${endpoint}`;
|
|
80
|
-
// [DEBUG]
|
|
81
|
-
console.error(`[API POST] User Token Len: ${apiKey?.length}, Anon Key Len: ${anonKey?.length}`);
|
|
82
114
|
const headers = {
|
|
83
|
-
'Authorization': `Bearer ${anonKey.trim()}`,
|
|
115
|
+
'Authorization': `Bearer ${anonKey.trim()}`,
|
|
84
116
|
'apikey': anonKey.trim(),
|
|
85
|
-
'x-api-key':
|
|
117
|
+
'x-api-key': apiKey.trim(), // [FIX] anonKey → apiKey 수정
|
|
86
118
|
'Content-Type': 'application/json',
|
|
87
119
|
};
|
|
88
120
|
const response = await fetch(url, {
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -7,14 +7,14 @@
|
|
|
7
7
|
"url": "https://github.com/kokogo100/ragalgo-mcp-server",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "1.0.
|
|
10
|
+
"version": "1.0.7",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"registry_type": "npm",
|
|
15
15
|
"registry_base_url": "https://registry.npmjs.org",
|
|
16
16
|
"identifier": "ragalgo-mcp-server",
|
|
17
|
-
"version": "1.0.
|
|
17
|
+
"version": "1.0.7",
|
|
18
18
|
"transport": {
|
|
19
19
|
"type": "stdio"
|
|
20
20
|
},
|