ragalgo-mcp-server 1.0.5 → 1.0.6

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.
@@ -5,7 +5,13 @@ import { z } from 'zod';
5
5
  export declare const TrendsParamsSchema: z.ZodObject<{
6
6
  tag_code: z.ZodString;
7
7
  days: z.ZodDefault<z.ZodNumber>;
8
- }, z.core.$strip>;
8
+ }, "strip", z.ZodTypeAny, {
9
+ tag_code: string;
10
+ days: number;
11
+ }, {
12
+ tag_code: string;
13
+ days?: number | undefined;
14
+ }>;
9
15
  export type TrendsParams = z.infer<typeof TrendsParamsSchema>;
10
16
  export declare function getTrends(params: TrendsParams): Promise<{
11
17
  success: boolean;
@@ -13,6 +19,7 @@ export declare function getTrends(params: TrendsParams): Promise<{
13
19
  code: string;
14
20
  name: string;
15
21
  type: string;
22
+ name_en?: string;
16
23
  };
17
24
  trend: Array<{
18
25
  date: string;
package/dist/utils/api.js CHANGED
@@ -2,20 +2,49 @@
2
2
  * RagAlgo API 유틸리티
3
3
  * Supabase Edge Functions 호출
4
4
  */
5
- const SUPABASE_URL = 'https://xunrsikkybgxkybjzrgz.supabase.co/functions/v1';
6
- const SUPABASE_ANON_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inh1bnJzaWtreWJneGt5Ymp6cmd6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjQ0NTExNTgsImV4cCI6MjA4MDAyNzE1OH0.SsXri828-Rf0gHlu4Bls-pewhfMNNII4mbiuLnc9ACs';
7
- // 환경변수에서 API 키 가져오기
8
- const getApiKey = () => {
9
- const key = process.env.RAGALGO_API_KEY;
10
- if (!key) {
11
- throw new Error('RAGALGO_API_KEY 환경변수가 설정되지 않았습니다.');
5
+ // [CHANGED] Dynamic URL Support
6
+ // If SUPABASE_URL is injected (from Desktop .env), use it. Otherwise fallback to hardcoded (Public default).
7
+ const DEFAULT_URL = 'https://xunrsikkybgxkybjzrgz.supabase.co/functions/v1';
8
+ const SUPABASE_URL = (process.env.SUPABASE_URL ? `${process.env.SUPABASE_URL}/functions/v1` : DEFAULT_URL).replace(/\/+$/, ''); // Remove trailing slash if double
9
+ // [DEBUG] Log active configuration
10
+ console.error(`[API Init] Target URL: ${SUPABASE_URL}`);
11
+ console.error(`[API Init] Env Override: ${!!process.env.SUPABASE_URL}`);
12
+ // [CHANGED] Get Keys from Environment (Injected by mcp_manager.py)
13
+ const getKeys = () => {
14
+ const apiKey = process.env.RAGALGO_API_KEY;
15
+ const anonKey = process.env.SUPABASE_ANON_KEY;
16
+ if (!apiKey) {
17
+ throw new Error('RAGALGO_API_KEY environment variable is missing.');
12
18
  }
13
- return key;
19
+ if (!anonKey) {
20
+ // Fallback for local testing if not injected, but log warning
21
+ console.error('[API] Warning: SUPABASE_ANON_KEY not found in env. Calls may fail.');
22
+ }
23
+ // [FALLBACK] Hardcoded Anon Key for reliability
24
+ const fallbackAnon = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Inh1bnJzaWtreWJneGt5Ymp6cmd6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjQ0NTExNTgsImV4cCI6MjA4MDAyNzE1OH0.SsXri828-Rf0gHlu4Bls-pewhfMNNII4mbiuLnc9ACs";
25
+ return { apiKey, anonKey: anonKey || fallbackAnon };
14
26
  };
15
27
  // API 호출 기본 함수
16
28
  export async function callApi(endpoint, params) {
17
- const apiKey = getApiKey();
29
+ 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}`);
18
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:
19
48
  const url = new URL(`${SUPABASE_URL}/${endpoint}`);
20
49
  if (params) {
21
50
  Object.entries(params).forEach(([key, value]) => {
@@ -24,35 +53,48 @@ export async function callApi(endpoint, params) {
24
53
  }
25
54
  });
26
55
  }
56
+ const headers = {
57
+ 'Authorization': `Bearer ${anonKey.trim()}`, // [FIX] Use Anon Key (JWT) for Supabase Gateway
58
+ 'apikey': anonKey.trim(),
59
+ 'x-api-key': apiKey.trim(), // [FIX] Use User API Key for x-api-key header
60
+ 'Content-Type': 'application/json',
61
+ };
27
62
  const response = await fetch(url.toString(), {
28
63
  method: 'GET',
29
- headers: {
30
- 'Authorization': `Bearer ${SUPABASE_ANON_KEY}`,
31
- 'x-api-key': apiKey,
32
- 'Content-Type': 'application/json',
33
- },
64
+ headers: headers,
34
65
  });
35
66
  if (!response.ok) {
36
67
  const error = await response.text();
37
- throw new Error(`API 호출 실패: ${response.status} - ${error}`);
68
+ const debugInfo = `[DEBUG] keys_present=${!!anonKey}, URL: ${url.toString()}`;
69
+ if (response.status === 429) {
70
+ throw new Error(`[RATE LIMIT EXCEEDED] API 요청 제한에 도달했습니다. 잠시 후 다시 시도하거나 요청량을 줄여주세요. (Plan Quota Exceeded) | ${debugInfo}`);
71
+ }
72
+ throw new Error(`API 호출 실패: ${response.status} - ${error} | ${debugInfo}`);
38
73
  }
39
74
  return response.json();
40
75
  }
41
76
  // POST API 호출
42
77
  export async function callApiPost(endpoint, body) {
43
- const apiKey = getApiKey();
78
+ const { apiKey, anonKey } = getKeys();
44
79
  const url = `${SUPABASE_URL}/${endpoint}`;
80
+ // [DEBUG]
81
+ console.error(`[API POST] User Token Len: ${apiKey?.length}, Anon Key Len: ${anonKey?.length}`);
82
+ const headers = {
83
+ 'Authorization': `Bearer ${anonKey.trim()}`, // [FIX] Use Anon Key (JWT)
84
+ 'apikey': anonKey.trim(),
85
+ 'x-api-key': anonKey.trim(), // [RESTORED]
86
+ 'Content-Type': 'application/json',
87
+ };
45
88
  const response = await fetch(url, {
46
89
  method: 'POST',
47
- headers: {
48
- 'Authorization': `Bearer ${SUPABASE_ANON_KEY}`,
49
- 'x-api-key': apiKey,
50
- 'Content-Type': 'application/json',
51
- },
90
+ headers: headers,
52
91
  body: JSON.stringify(body),
53
92
  });
54
93
  if (!response.ok) {
55
94
  const error = await response.text();
95
+ if (response.status === 429) {
96
+ throw new Error(`[RATE LIMIT EXCEEDED] API 요청 제한에 도달했습니다. 잠시 후 다시 시도하거나 요청량을 줄여주세요. (Plan Quota Exceeded)`);
97
+ }
56
98
  throw new Error(`API 호출 실패: ${response.status} - ${error}`);
57
99
  }
58
100
  return response.json();
package/package.json CHANGED
@@ -1,41 +1,47 @@
1
1
  {
2
- "name": "ragalgo-mcp-server",
3
- "version": "1.0.5",
4
- "files": [
5
- "dist"
6
- ],
7
- "description": "Dynamic RAG Engine for AI Reliability. We provide mathematically scored context & sanitized data to prevent hallucinations in both static & volatile domains (starting with Korean Finance).",
8
- "author": "",
9
- "main": "dist/index.js",
10
- "bin": {
11
- "ragalgo-mcp-server": "./dist/index.js"
12
- },
13
- "type": "module",
14
- "scripts": {
15
- "build": "npx tsc",
16
- "start": "node dist/index.js",
17
- "dev": "npx tsx src/index.ts"
18
- },
19
- "keywords": [
20
- "mcp",
21
- "ragalgo",
22
- "finance",
23
- "news",
24
- "ai"
25
- ],
26
- "license": "MIT",
27
- "dependencies": {
28
- "@modelcontextprotocol/sdk": "^1.0.0",
29
- "cors": "^2.8.5",
30
- "express": "^5.2.1",
31
- "zod": "^4.3.5",
32
- "zod-to-json-schema": "^3.25.1"
33
- },
34
- "devDependencies": {
35
- "@types/cors": "^2.8.19",
36
- "@types/express": "^5.0.6",
37
- "@types/node": "^20.19.26",
38
- "tsx": "^4.21.0",
39
- "typescript": "^5.9.3"
40
- }
2
+ "name": "ragalgo-mcp-server",
3
+ "version": "1.0.6",
4
+ "mcpName": "io.github.kokogo100/ragalgo",
5
+ "files": [
6
+ "dist",
7
+ "README.md",
8
+ "server.json"
9
+ ],
10
+ "description": "Dynamic RAG Engine for AI Reliability. We provide mathematically scored context & sanitized data to prevent hallucinations in both static & volatile domains (starting with Korean Finance).",
11
+ "main": "dist/index.js",
12
+ "bin": {
13
+ "ragalgo-mcp-server": "./dist/index.js"
14
+ },
15
+ "type": "module",
16
+ "scripts": {
17
+ "build": "npx tsc",
18
+ "start": "node dist/index.js",
19
+ "dev": "npx tsx src/index.ts"
20
+ },
21
+ "keywords": [
22
+ "mcp",
23
+ "rag",
24
+ "ai-reliability",
25
+ "context-scoring",
26
+ "finance",
27
+ "korea-market"
28
+ ],
29
+ "author": "RagAlgo Team",
30
+ "license": "MIT",
31
+ "dependencies": {
32
+ "@modelcontextprotocol/sdk": "^1.0.0",
33
+ "@types/uuid": "^10.0.0",
34
+ "cors": "^2.8.5",
35
+ "express": "^4.21.2",
36
+ "uuid": "^13.0.0",
37
+ "zod": "^3.25.0",
38
+ "zod-to-json-schema": "^3.25.1"
39
+ },
40
+ "devDependencies": {
41
+ "@types/cors": "^2.8.19",
42
+ "@types/express": "^5.0.6",
43
+ "@types/node": "^20.19.26",
44
+ "tsx": "^4.21.0",
45
+ "typescript": "^5.9.3"
46
+ }
41
47
  }
package/server.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
3
+ "name": "io.github.kokogo100/ragalgo",
4
+ "description": "Dynamic RAG Engine preventing AI hallucinations in Korean Finance and Crypto markets.",
5
+ "status": "active",
6
+ "repository": {
7
+ "url": "https://github.com/kokogo100/ragalgo-mcp-server",
8
+ "source": "github"
9
+ },
10
+ "version": "1.0.0",
11
+ "packages": [
12
+ {
13
+ "registryType": "npm",
14
+ "registry_type": "npm",
15
+ "registry_base_url": "https://registry.npmjs.org",
16
+ "identifier": "ragalgo-mcp-server",
17
+ "version": "1.0.4",
18
+ "transport": {
19
+ "type": "stdio"
20
+ },
21
+ "environment_variables": [
22
+ {
23
+ "description": "Your API key for the RagAlgo service",
24
+ "is_required": true,
25
+ "format": "string",
26
+ "is_secret": true,
27
+ "name": "RAGALGO_API_KEY"
28
+ }
29
+ ]
30
+ }
31
+ ]
32
+ }