redash-mcp 2.0.2 → 2.0.4

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.
@@ -1,10 +1,20 @@
1
1
  {
2
2
  "permissions": {
3
3
  "allow": [
4
+ "Bash(git clone:*)",
4
5
  "Bash(npm:*)",
5
- "Bash(rm:*)",
6
- "mcp__plugin_oh-my-claudecode_t__state_list_active",
7
- "mcp__plugin_oh-my-claudecode_t__state_clear"
6
+ "Bash(git push:*)",
7
+ "WebFetch(domain:registry.npmjs.org)",
8
+ "Bash(NPM_TOKEN=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 npm publish:*)"
8
9
  ]
10
+ },
11
+ "enabledMcpjsonServers": [
12
+ "context7",
13
+ "filesystem",
14
+ "github"
15
+ ],
16
+ "sandbox": {
17
+ "enabled": true,
18
+ "autoAllowBashIfSandboxed": true
9
19
  }
10
20
  }
package/README.md CHANGED
@@ -25,13 +25,23 @@
25
25
  | 알림 | `get_alert` | 알림 상세 정보 조회 |
26
26
  | 알림 | `create_alert` | 새 알림 생성 |
27
27
 
28
- ## 설치 (Claude Desktop)
28
+ ## 설치
29
29
 
30
- ### 1. Redash API 키 발급
30
+ ### 자동 설치 (권장)
31
+
32
+ ```bash
33
+ npx redash-mcp setup
34
+ ```
35
+
36
+ 설치 마법사가 실행되며 Claude Desktop, Claude Code(CLI), 또는 둘 다 선택하여 설정할 수 있습니다.
37
+
38
+ ### 수동 설치
39
+
40
+ #### 1. Redash API 키 발급
31
41
 
32
42
  Redash → 우측 상단 프로필 → **Edit Profile** → **API Key** 복사
33
43
 
34
- ### 2. Claude Desktop 설정
44
+ #### 2-A. Claude Desktop 설정
35
45
 
36
46
  `~/Library/Application Support/Claude/claude_desktop_config.json` 파일을 열고 아래 내용을 추가합니다:
37
47
 
@@ -50,12 +60,31 @@ Redash → 우측 상단 프로필 → **Edit Profile** → **API Key** 복사
50
60
  }
51
61
  ```
52
62
 
53
- > **Windows/Linux**: `command`를 `npx`로 그대로 사용하면 됩니다.
54
- > **macOS**: `npx`를 못 찾는 경우 `which npx` 명령어로 전체 경로를 확인 후 대체하세요.
63
+ 설정 저장 Claude Desktop을 완전히 종료했다가 다시 시작합니다.
55
64
 
56
- ### 3. Claude Desktop 재시작
65
+ #### 2-B. Claude Code (CLI) 설정
57
66
 
58
- 설정 저장 Claude Desktop을 완전히 종료했다가 다시 시작합니다.
67
+ `~/.claude/settings.json` 파일을 열고 아래 내용을 추가합니다:
68
+
69
+ ```json
70
+ {
71
+ "mcpServers": {
72
+ "redash-mcp": {
73
+ "command": "npx",
74
+ "args": ["-y", "redash-mcp"],
75
+ "env": {
76
+ "REDASH_URL": "https://your-redash-instance.com",
77
+ "REDASH_API_KEY": "your_api_key_here"
78
+ }
79
+ }
80
+ }
81
+ }
82
+ ```
83
+
84
+ 새 Claude Code 세션에서 바로 사용할 수 있습니다.
85
+
86
+ > **Windows/Linux**: `command`를 `npx`로 그대로 사용하면 됩니다.
87
+ > **macOS**: `npx`를 못 찾는 경우 `which npx` 명령어로 전체 경로를 확인 후 대체하세요.
59
88
 
60
89
  ## 환경 변수
61
90
 
package/dist/setup.js CHANGED
@@ -2,10 +2,8 @@
2
2
  import * as fs from "fs";
3
3
  import * as path from "path";
4
4
  import * as os from "os";
5
- import * as readline from "readline";
6
5
  import { execSync } from "child_process";
7
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
8
- const ask = (q) => new Promise((res) => rl.question(q, res));
6
+ import * as p from "@clack/prompts";
9
7
  function findNpxPath() {
10
8
  try {
11
9
  const result = execSync("which npx", { encoding: "utf8" }).trim();
@@ -18,13 +16,13 @@ function findNpxPath() {
18
16
  "/opt/homebrew/bin/npx",
19
17
  "/usr/bin/npx",
20
18
  ];
21
- for (const p of candidates) {
22
- if (fs.existsSync(p))
23
- return p;
19
+ for (const c of candidates) {
20
+ if (fs.existsSync(c))
21
+ return c;
24
22
  }
25
23
  return "npx";
26
24
  }
27
- function getConfigPath() {
25
+ function getDesktopConfigPath() {
28
26
  const platform = os.platform();
29
27
  if (platform === "darwin") {
30
28
  return path.join(os.homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
@@ -36,16 +34,73 @@ function getConfigPath() {
36
34
  return path.join(os.homedir(), ".config", "Claude", "claude_desktop_config.json");
37
35
  }
38
36
  }
37
+ function getClaudeCodeConfigPath() {
38
+ return path.join(os.homedir(), ".claude", "settings.json");
39
+ }
39
40
  export async function main() {
40
- console.log("\n🔧 redash-mcp 설치 마법사\n");
41
- const redashUrl = (await ask("Redash URL을 입력하세요 (예: https://redash.example.com): ")).trim().replace(/\/$/, "");
42
- const apiKey = (await ask("Redash API 키를 입력하세요: ")).trim();
43
- rl.close();
44
- if (!redashUrl || !apiKey) {
45
- console.error("\n❌ URL과 API 키를 모두 입력해야 합니다.");
46
- process.exit(1);
41
+ p.intro("redash-mcp 설치 마법사");
42
+ const targets = await p.multiselect({
43
+ message: "설치 대상을 선택하세요 (스페이스바로 선택, 엔터로 확인)",
44
+ options: [
45
+ { value: "desktop", label: "Claude Desktop" },
46
+ { value: "cli", label: "Claude Code (CLI)" },
47
+ ],
48
+ required: true,
49
+ });
50
+ if (p.isCancel(targets)) {
51
+ p.cancel("설치가 취소되었습니다.");
52
+ process.exit(0);
53
+ }
54
+ const redashUrl = await p.text({
55
+ message: "Redash URL을 입력하세요",
56
+ placeholder: "https://redash.example.com",
57
+ validate(value) {
58
+ if (!value)
59
+ return "URL을 입력해주세요.";
60
+ if (!value.startsWith("http://") && !value.startsWith("https://"))
61
+ return "http:// 또는 https://로 시작해야 합니다.";
62
+ },
63
+ });
64
+ if (p.isCancel(redashUrl)) {
65
+ p.cancel("설치가 취소되었습니다.");
66
+ process.exit(0);
67
+ }
68
+ const apiKey = await p.text({
69
+ message: "Redash API 키를 입력하세요",
70
+ validate(value) {
71
+ if (!value)
72
+ return "API 키를 입력해주세요.";
73
+ },
74
+ });
75
+ if (p.isCancel(apiKey)) {
76
+ p.cancel("설치가 취소되었습니다.");
77
+ process.exit(0);
47
78
  }
48
- const configPath = getConfigPath();
79
+ const url = redashUrl.replace(/\/$/, "");
80
+ const npxPath = findNpxPath();
81
+ const mcpEntry = {
82
+ command: npxPath,
83
+ args: ["-y", "redash-mcp"],
84
+ env: {
85
+ REDASH_URL: url,
86
+ REDASH_API_KEY: apiKey,
87
+ },
88
+ };
89
+ const s = p.spinner();
90
+ if (targets.includes("desktop")) {
91
+ s.start("Claude Desktop 설정 중...");
92
+ setupDesktop(mcpEntry);
93
+ s.stop("Claude Desktop 설정 완료");
94
+ }
95
+ if (targets.includes("cli")) {
96
+ s.start("Claude Code (CLI) 설정 중...");
97
+ setupClaudeCode(mcpEntry);
98
+ s.stop("Claude Code (CLI) 설정 완료");
99
+ }
100
+ p.outro("설치가 완료되었습니다. 재시작 후 사용할 수 있습니다.");
101
+ }
102
+ function setupDesktop(mcpEntry) {
103
+ const configPath = getDesktopConfigPath();
49
104
  let config = { mcpServers: {} };
50
105
  if (fs.existsSync(configPath)) {
51
106
  try {
@@ -53,24 +108,30 @@ export async function main() {
53
108
  config.mcpServers ??= {};
54
109
  }
55
110
  catch {
56
- console.error("\n❌ claude_desktop_config.json 파일을 읽을 수 없습니다.");
57
- process.exit(1);
111
+ throw new Error(`claude_desktop_config.json 파일을 읽을 수 없습니다: ${configPath}`);
58
112
  }
59
113
  }
60
114
  else {
61
115
  fs.mkdirSync(path.dirname(configPath), { recursive: true });
62
116
  }
63
- const npxPath = findNpxPath();
64
- config.mcpServers["redash-mcp"] = {
65
- command: npxPath,
66
- args: ["-y", "redash-mcp"],
67
- env: {
68
- REDASH_URL: redashUrl,
69
- REDASH_API_KEY: apiKey,
70
- },
71
- };
117
+ config.mcpServers["redash-mcp"] = mcpEntry;
118
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf8");
119
+ }
120
+ function setupClaudeCode(mcpEntry) {
121
+ const configPath = getClaudeCodeConfigPath();
122
+ let config = {};
123
+ if (fs.existsSync(configPath)) {
124
+ try {
125
+ config = JSON.parse(fs.readFileSync(configPath, "utf8"));
126
+ }
127
+ catch {
128
+ throw new Error(`Claude Code settings.json 파일을 읽을 수 없습니다: ${configPath}`);
129
+ }
130
+ }
131
+ else {
132
+ fs.mkdirSync(path.dirname(configPath), { recursive: true });
133
+ }
134
+ config.mcpServers ??= {};
135
+ config.mcpServers["redash-mcp"] = mcpEntry;
72
136
  fs.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf8");
73
- console.log("\n✅ 설치 완료!");
74
- console.log(` 설정 파일: ${configPath}`);
75
- console.log("\n👉 Claude Desktop을 완전히 종료했다가 다시 시작하면 redash-mcp가 활성화됩니다.\n");
76
137
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "redash-mcp",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "MCP server for Redash",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -13,6 +13,7 @@
13
13
  "start": "node dist/index.js"
14
14
  },
15
15
  "dependencies": {
16
+ "@clack/prompts": "^1.1.0",
16
17
  "@modelcontextprotocol/sdk": "^1.0.0",
17
18
  "zod": "^3.0.0"
18
19
  },