redash-mcp 3.1.5 → 3.1.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.
- package/README.ja.md +13 -0
- package/README.ko.md +13 -0
- package/README.md +13 -0
- package/dist/index.js +74 -68
- package/glama.json +6 -0
- package/manifest.json +1 -1
- package/package.json +1 -1
package/README.ja.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/redash-mcp)
|
|
5
5
|
[](https://nodejs.org)
|
|
6
6
|
[](https://smithery.ai/servers/dev-seob717/redash-mcp)
|
|
7
|
+
[](https://glama.ai/mcp/servers/seob717/redash-mcp)
|
|
7
8
|
|
|
8
9
|
[English](README.md) | [한국어](README.ko.md) | 日本語
|
|
9
10
|
|
|
@@ -11,6 +12,8 @@
|
|
|
11
12
|
|
|
12
13
|
[なぜ redash-mcp か](#なぜ-redash-mcp-か) · [機能](#機能) · [インストール](#インストール) · [環境変数](#環境変数) · [使用例](#使用例) · [Privacy](#privacy-policy)
|
|
13
14
|
|
|
15
|
+

|
|
16
|
+
|
|
14
17
|
> 英語版 README との最終同期: 2026-06-09
|
|
15
18
|
|
|
16
19
|
---
|
|
@@ -252,3 +255,13 @@ redash-mcp は **ローカル MCP サーバー** であり、ユーザーの Red
|
|
|
252
255
|
### 連絡先
|
|
253
256
|
|
|
254
257
|
お問い合わせ・セキュリティ報告: [GitHub Issues](https://github.com/seob717/redash-mcp/issues)
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## 免責事項 (Disclaimer)
|
|
262
|
+
|
|
263
|
+
redash-mcp はコミュニティが開発した非公式の統合ツールであり、**Redash とは提携・承認・後援のいずれの関係もありません**。「Redash」は各権利者の商標であり、ここでは互換性を説明する目的でのみ使用しています。本プロジェクトは Redash の公開 REST API を通じてのみ通信します。
|
|
264
|
+
|
|
265
|
+
## ライセンス
|
|
266
|
+
|
|
267
|
+
MIT © seob717
|
package/README.ko.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/redash-mcp)
|
|
5
5
|
[](https://nodejs.org)
|
|
6
6
|
[](https://smithery.ai/servers/dev-seob717/redash-mcp)
|
|
7
|
+
[](https://glama.ai/mcp/servers/seob717/redash-mcp)
|
|
7
8
|
|
|
8
9
|
[English](README.md) | 한국어 | [日本語](README.ja.md)
|
|
9
10
|
|
|
@@ -11,6 +12,8 @@
|
|
|
11
12
|
|
|
12
13
|
[왜 redash-mcp인가](#왜-redash-mcp인가) · [기능](#기능) · [설치](#설치) · [환경 변수](#환경-변수) · [사용 예시](#사용-예시) · [Privacy](#privacy-policy)
|
|
13
14
|
|
|
15
|
+

|
|
16
|
+
|
|
14
17
|
> 영문 README와 마지막 동기화: 2026-06-09
|
|
15
18
|
|
|
16
19
|
---
|
|
@@ -252,3 +255,13 @@ redash-mcp는 **로컬 MCP 서버**로, 사용자의 Redash 인스턴스와 직
|
|
|
252
255
|
### 연락처
|
|
253
256
|
|
|
254
257
|
문의 및 보안 이슈 보고: [GitHub Issues](https://github.com/seob717/redash-mcp/issues)
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## 고지 (Disclaimer)
|
|
262
|
+
|
|
263
|
+
redash-mcp는 커뮤니티가 만든 비공식 통합 도구이며, **Redash와 제휴·보증·후원 관계가 없습니다**. "Redash"는 해당 상표권자의 상표이며, 여기서는 호환성을 설명하기 위한 용도로만 사용합니다. 이 프로젝트는 Redash의 공개 REST API를 통해서만 통신합니다.
|
|
264
|
+
|
|
265
|
+
## 라이선스
|
|
266
|
+
|
|
267
|
+
MIT © seob717
|
package/README.md
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
[](https://www.npmjs.com/package/redash-mcp)
|
|
5
5
|
[](https://nodejs.org)
|
|
6
6
|
[](https://smithery.ai/servers/dev-seob717/redash-mcp)
|
|
7
|
+
[](https://glama.ai/mcp/servers/seob717/redash-mcp)
|
|
7
8
|
|
|
8
9
|
English | [한국어](README.ko.md) | [日本語](README.ja.md)
|
|
9
10
|
|
|
@@ -11,6 +12,8 @@ English | [한국어](README.ko.md) | [日本語](README.ja.md)
|
|
|
11
12
|
|
|
12
13
|
[Why](#why-redash-mcp) · [Features](#features) · [Install](#installation) · [Env](#environment-variables) · [Examples](#usage-examples) · [Privacy](#privacy-policy)
|
|
13
14
|
|
|
15
|
+

|
|
16
|
+
|
|
14
17
|
---
|
|
15
18
|
|
|
16
19
|
## Why redash-mcp?
|
|
@@ -250,3 +253,13 @@ We do not sell or share user data with third parties. When the LLM Fallback feat
|
|
|
250
253
|
### Contact
|
|
251
254
|
|
|
252
255
|
For inquiries and security reports: [GitHub Issues](https://github.com/seob717/redash-mcp/issues)
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Disclaimer
|
|
260
|
+
|
|
261
|
+
redash-mcp is an unofficial, community-built integration and is **not affiliated with, endorsed by, or sponsored by Redash**. "Redash" is a trademark of its respective owners and is used here only to describe compatibility. This project communicates with Redash solely through its public REST API.
|
|
262
|
+
|
|
263
|
+
## License
|
|
264
|
+
|
|
265
|
+
MIT © seob717
|
package/dist/index.js
CHANGED
|
@@ -8610,12 +8610,13 @@ ${c}
|
|
|
8610
8610
|
// src/setup.ts
|
|
8611
8611
|
var setup_exports = {};
|
|
8612
8612
|
__export(setup_exports, {
|
|
8613
|
+
buildClaudeMcpAddArgs: () => buildClaudeMcpAddArgs,
|
|
8613
8614
|
main: () => main
|
|
8614
8615
|
});
|
|
8615
8616
|
import * as fs from "fs";
|
|
8616
8617
|
import * as path3 from "path";
|
|
8617
8618
|
import * as os2 from "os";
|
|
8618
|
-
import { execSync } from "child_process";
|
|
8619
|
+
import { execFileSync, execSync } from "child_process";
|
|
8619
8620
|
function findNpxPath() {
|
|
8620
8621
|
try {
|
|
8621
8622
|
const result = execSync("which npx", { encoding: "utf8" }).trim();
|
|
@@ -8642,8 +8643,18 @@ function getDesktopConfigPath() {
|
|
|
8642
8643
|
return path3.join(os2.homedir(), ".config", "Claude", "claude_desktop_config.json");
|
|
8643
8644
|
}
|
|
8644
8645
|
}
|
|
8645
|
-
function
|
|
8646
|
-
return
|
|
8646
|
+
function buildClaudeMcpAddArgs(mcpEntry) {
|
|
8647
|
+
return [
|
|
8648
|
+
"mcp",
|
|
8649
|
+
"add",
|
|
8650
|
+
"--scope",
|
|
8651
|
+
"user",
|
|
8652
|
+
"redash-mcp",
|
|
8653
|
+
...Object.entries(mcpEntry.env).flatMap(([key, value]) => ["-e", `${key}=${value}`]),
|
|
8654
|
+
"--",
|
|
8655
|
+
mcpEntry.command,
|
|
8656
|
+
...mcpEntry.args
|
|
8657
|
+
];
|
|
8647
8658
|
}
|
|
8648
8659
|
async function main() {
|
|
8649
8660
|
ge("redash-mcp setup wizard");
|
|
@@ -8722,20 +8733,15 @@ function setupDesktop(mcpEntry) {
|
|
|
8722
8733
|
fs.writeFileSync(configPath, JSON.stringify(config2, null, 2), "utf8");
|
|
8723
8734
|
}
|
|
8724
8735
|
function setupClaudeCode(mcpEntry) {
|
|
8725
|
-
const
|
|
8726
|
-
|
|
8727
|
-
|
|
8728
|
-
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
|
|
8732
|
-
|
|
8733
|
-
} else {
|
|
8734
|
-
fs.mkdirSync(path3.dirname(configPath), { recursive: true });
|
|
8736
|
+
const args = buildClaudeMcpAddArgs(mcpEntry);
|
|
8737
|
+
try {
|
|
8738
|
+
execFileSync("claude", args, { stdio: "pipe" });
|
|
8739
|
+
} catch {
|
|
8740
|
+
throw new Error(
|
|
8741
|
+
`Failed to run "claude mcp add". Make sure the Claude Code CLI is installed, or run manually:
|
|
8742
|
+
claude ${args.join(" ")}`
|
|
8743
|
+
);
|
|
8735
8744
|
}
|
|
8736
|
-
config2.mcpServers ??= {};
|
|
8737
|
-
config2.mcpServers["redash-mcp"] = mcpEntry;
|
|
8738
|
-
fs.writeFileSync(configPath, JSON.stringify(config2, null, 2), "utf8");
|
|
8739
8745
|
}
|
|
8740
8746
|
var init_setup = __esm({
|
|
8741
8747
|
"src/setup.ts"() {
|
|
@@ -42130,7 +42136,7 @@ ${result.guidance}`);
|
|
|
42130
42136
|
);
|
|
42131
42137
|
server2.tool(
|
|
42132
42138
|
"manage_few_shot_examples",
|
|
42133
|
-
"Manage few-shot examples
|
|
42139
|
+
"Manage the few-shot examples that smart_query uses to generate more accurate SQL. Behavior: action 'list' returns all stored examples with their ids; 'add' saves a new example (requires the example object); 'remove' deletes one (requires example_id). Each example pairs a natural-language question with the correct SQL and the tables it uses, teaching the model your schema's domain conventions. Usage: examples are stored locally per data_source_id and are retrieved automatically by smart_query \u2014 register a few for recurring question patterns to raise accuracy.",
|
|
42134
42140
|
{
|
|
42135
42141
|
data_source_id: external_exports.number().describe("Data source ID"),
|
|
42136
42142
|
action: external_exports.enum(["list", "add", "remove"]).describe("Action to perform"),
|
|
@@ -42200,7 +42206,7 @@ ${text}` }] };
|
|
|
42200
42206
|
);
|
|
42201
42207
|
server2.tool(
|
|
42202
42208
|
"submit_query_feedback",
|
|
42203
|
-
"
|
|
42209
|
+
"Record whether the SQL produced for a question was correct, so smart_query improves over time. Behavior: stores an up/down rating; when you rate 'down' and supply the correct SQL, the error is classified and, if the same kind of mistake recurs, automatically promoted into a few-shot example. Returns the feedback id and any error type or promotion. Usage: call after reviewing smart_query/run_query output; feedback is stored locally per data_source_id and feeds the learning loop.",
|
|
42204
42210
|
{
|
|
42205
42211
|
data_source_id: external_exports.number().describe("Data source ID"),
|
|
42206
42212
|
question: external_exports.string().describe("Original natural-language question"),
|
|
@@ -42232,7 +42238,7 @@ ${text}` }] };
|
|
|
42232
42238
|
);
|
|
42233
42239
|
server2.tool(
|
|
42234
42240
|
"evaluate_queries",
|
|
42235
|
-
"
|
|
42241
|
+
"Build and run an accuracy test suite for SQL generation on a data source. Behavior: action 'add_test' stores a question paired with ground-truth SQL; 'list_tests' shows them; 'remove_test' deletes one; 'run' scores generated SQL against the test cases; 'results' shows the latest run. Usage: use this to measure whether keyword maps and few-shot examples actually improve smart_query accuracy over time; test cases and runs are stored locally per data_source_id.",
|
|
42236
42242
|
{
|
|
42237
42243
|
data_source_id: external_exports.number().describe("Data source ID"),
|
|
42238
42244
|
action: external_exports.enum(["list_tests", "add_test", "remove_test", "run", "results"]).describe("Action to perform"),
|
|
@@ -42503,7 +42509,7 @@ ${tables.join("\n")}`;
|
|
|
42503
42509
|
);
|
|
42504
42510
|
server.tool(
|
|
42505
42511
|
"get_table_columns",
|
|
42506
|
-
"Get column names and types for one or more tables
|
|
42512
|
+
"Get the column names and data types for one or more tables in a data source. Accepts a single table or a comma-separated list of tables. Use this to confirm exact column names and types before writing SQL with run_query or smart_query. Returns each table's columns; if a table name is not found, it suggests verifying it with list_tables.",
|
|
42507
42513
|
{
|
|
42508
42514
|
data_source_id: external_exports.number().describe("Data source ID from list_data_sources"),
|
|
42509
42515
|
table_name: external_exports.string().describe("Table name(s), comma-separated (e.g., 'users' or 'users,orders')")
|
|
@@ -42543,7 +42549,7 @@ var MAX_TIMEOUT_SECS = 300;
|
|
|
42543
42549
|
var MAX_CACHE_AGE_SECS = 86400 * 7;
|
|
42544
42550
|
server.tool(
|
|
42545
42551
|
"run_query",
|
|
42546
|
-
"Execute SQL against a data source and return results.
|
|
42552
|
+
"Execute an ad-hoc SQL query against a data source and return the resulting rows. Every query passes through the SQL safety guard, which blocks destructive statements (DROP/TRUNCATE/ALTER, DELETE/UPDATE without WHERE) and flags PII columns and expensive full scans; results are cached in memory. Behavior: returns up to max_rows rows as a markdown table or JSON, with the column list and a truncation note when there are more rows. Usage: confirm table and column names with list_tables and get_table_columns first; for natural-language questions, plan the SQL with smart_query before calling this. To run an already-saved query instead, use get_query_result.",
|
|
42547
42553
|
{
|
|
42548
42554
|
data_source_id: external_exports.number().int().nonnegative().describe("Data source ID from list_data_sources"),
|
|
42549
42555
|
query: external_exports.string().describe("SQL query to execute"),
|
|
@@ -42628,11 +42634,11 @@ ${body}`
|
|
|
42628
42634
|
);
|
|
42629
42635
|
server.tool(
|
|
42630
42636
|
"list_queries",
|
|
42631
|
-
"List saved queries in Redash.",
|
|
42637
|
+
"List saved (named) queries in Redash, most recently updated first. Behavior: returns a paginated array where each item has id, name, description, data_source_id, and updated_at. Usage: use this to discover query_ids, then call get_query for a query's full SQL and visualizations, or get_query_result to run it. Supports keyword search and pagination; for ad-hoc SQL that isn't saved, use run_query instead.",
|
|
42632
42638
|
{
|
|
42633
|
-
search: external_exports.string().optional().describe("
|
|
42634
|
-
page: external_exports.number().optional().default(1),
|
|
42635
|
-
page_size: external_exports.number().optional().default(20).describe("
|
|
42639
|
+
search: external_exports.string().optional().describe("Optional keyword to filter queries by name/description"),
|
|
42640
|
+
page: external_exports.number().optional().default(1).describe("Page number to fetch, 1-based (default 1)"),
|
|
42641
|
+
page_size: external_exports.number().optional().default(20).describe("Number of queries per page, 1-100 (default 20)")
|
|
42636
42642
|
},
|
|
42637
42643
|
{ readOnlyHint: true },
|
|
42638
42644
|
async ({ search, page, page_size }) => {
|
|
@@ -42662,9 +42668,9 @@ server.tool(
|
|
|
42662
42668
|
);
|
|
42663
42669
|
server.tool(
|
|
42664
42670
|
"get_query_result",
|
|
42665
|
-
"
|
|
42671
|
+
"Run an existing saved query by its ID and return the latest results. Behavior: executes the query as stored in Redash and returns up to max_rows rows as a markdown table or JSON, with the column list and a truncation note. Usage: find the query_id with list_queries or get_query. Unlike run_query, this executes already-saved SQL rather than ad-hoc SQL, so the safety guard does not apply.",
|
|
42666
42672
|
{
|
|
42667
|
-
query_id: external_exports.number().int().nonnegative().describe("
|
|
42673
|
+
query_id: external_exports.number().int().nonnegative().describe("ID of the saved query to run (from list_queries)"),
|
|
42668
42674
|
max_rows: external_exports.number().int().min(1).max(MAX_ROWS_LIMIT).optional().default(100).describe(`Max rows to return (1 to ${MAX_ROWS_LIMIT}, default 100)`),
|
|
42669
42675
|
format: external_exports.enum(["table", "json"]).optional().default("table").describe("Output format: table (markdown) or json"),
|
|
42670
42676
|
timeout_secs: external_exports.number().int().min(1).max(MAX_TIMEOUT_SECS).optional().default(30).describe(`Query execution timeout in seconds (1 to ${MAX_TIMEOUT_SECS}, default 30)`)
|
|
@@ -42712,9 +42718,9 @@ ${body}`
|
|
|
42712
42718
|
);
|
|
42713
42719
|
server.tool(
|
|
42714
42720
|
"get_query",
|
|
42715
|
-
"Get saved query
|
|
42721
|
+
"Get the full definition of a saved query. Behavior: returns the query's SQL text, data_source_id, tags, owner, update time, and its visualizations (each with id, name, type). Usage: find the query_id with list_queries. The returned visualization ids can be placed on a dashboard with add_widget; to actually run the query use get_query_result.",
|
|
42716
42722
|
{
|
|
42717
|
-
query_id: external_exports.number().describe("
|
|
42723
|
+
query_id: external_exports.number().describe("ID of the saved query to inspect (from list_queries)")
|
|
42718
42724
|
},
|
|
42719
42725
|
{ readOnlyHint: true },
|
|
42720
42726
|
async ({ query_id }) => {
|
|
@@ -42742,13 +42748,13 @@ server.tool(
|
|
|
42742
42748
|
);
|
|
42743
42749
|
server.tool(
|
|
42744
42750
|
"create_query",
|
|
42745
|
-
"Save a new query to Redash.",
|
|
42751
|
+
"Save a new named SQL query to Redash so it can be reused, scheduled, visualized, or added to a dashboard. Behavior: creates the query and returns its new id, name, and created_at. Usage: get the data_source_id from list_data_sources and verify the SQL runs with run_query first; to change an existing query use update_query instead. Note: this only saves the query \u2014 use get_query_result to execute it.",
|
|
42746
42752
|
{
|
|
42747
|
-
name: external_exports.string().describe("
|
|
42748
|
-
query: external_exports.string().describe("SQL
|
|
42749
|
-
data_source_id: external_exports.number().describe("
|
|
42750
|
-
description: external_exports.string().optional().describe("
|
|
42751
|
-
tags: external_exports.array(external_exports.string()).optional().describe("
|
|
42753
|
+
name: external_exports.string().describe("Display name for the saved query"),
|
|
42754
|
+
query: external_exports.string().describe("The SQL statement to save"),
|
|
42755
|
+
data_source_id: external_exports.number().describe("ID of the data source this query runs against (from list_data_sources)"),
|
|
42756
|
+
description: external_exports.string().optional().describe("Optional human-readable description of what the query does"),
|
|
42757
|
+
tags: external_exports.array(external_exports.string()).optional().describe("Optional tags to categorize the query (e.g., ['finance', 'weekly'])")
|
|
42752
42758
|
},
|
|
42753
42759
|
{ destructiveHint: true },
|
|
42754
42760
|
async ({ name, query, data_source_id, description, tags }) => {
|
|
@@ -42775,13 +42781,13 @@ server.tool(
|
|
|
42775
42781
|
);
|
|
42776
42782
|
server.tool(
|
|
42777
42783
|
"update_query",
|
|
42778
|
-
"Update
|
|
42784
|
+
"Update fields of an existing saved query. Behavior: only the fields you pass are changed (name, SQL, description, or tags); any omitted field is left untouched. Returns the query's id, name, and updated_at. Usage: find the query_id with list_queries or get_query; to create a brand-new query instead, use create_query.",
|
|
42779
42785
|
{
|
|
42780
|
-
query_id: external_exports.number().describe("
|
|
42781
|
-
name: external_exports.string().optional().describe("New name"),
|
|
42782
|
-
query: external_exports.string().optional().describe("New SQL"),
|
|
42783
|
-
description: external_exports.string().optional().describe("New description"),
|
|
42784
|
-
tags: external_exports.array(external_exports.string()).optional().describe("New tags")
|
|
42786
|
+
query_id: external_exports.number().describe("ID of the saved query to update (from list_queries)"),
|
|
42787
|
+
name: external_exports.string().optional().describe("New display name (omit to keep current)"),
|
|
42788
|
+
query: external_exports.string().optional().describe("New SQL statement (omit to keep current)"),
|
|
42789
|
+
description: external_exports.string().optional().describe("New description (omit to keep current)"),
|
|
42790
|
+
tags: external_exports.array(external_exports.string()).optional().describe("New tag list, replacing the existing tags (omit to keep current)")
|
|
42785
42791
|
},
|
|
42786
42792
|
{ destructiveHint: true },
|
|
42787
42793
|
async ({ query_id, name, query, description, tags }) => {
|
|
@@ -42810,9 +42816,9 @@ server.tool(
|
|
|
42810
42816
|
);
|
|
42811
42817
|
server.tool(
|
|
42812
42818
|
"fork_query",
|
|
42813
|
-
"Fork (duplicate) an existing query.",
|
|
42819
|
+
"Fork (duplicate) an existing saved query into a new, independently editable copy, leaving the original unchanged. Behavior: creates the copy and returns its new id and name. Usage: find the query_id to fork with list_queries; use this when you want to experiment with or adapt a query without modifying the original.",
|
|
42814
42820
|
{
|
|
42815
|
-
query_id: external_exports.number().describe("
|
|
42821
|
+
query_id: external_exports.number().describe("ID of the saved query to duplicate (from list_queries)")
|
|
42816
42822
|
},
|
|
42817
42823
|
{ destructiveHint: true },
|
|
42818
42824
|
async ({ query_id }) => {
|
|
@@ -42836,9 +42842,9 @@ server.tool(
|
|
|
42836
42842
|
);
|
|
42837
42843
|
server.tool(
|
|
42838
42844
|
"archive_query",
|
|
42839
|
-
"Archive
|
|
42845
|
+
"Archive a saved query, removing it from active query lists. This is Redash's form of deletion and cannot be undone through the API, so confirm with the user before calling it. Behavior: archives the query and returns a confirmation message. Usage: find the query_id with list_queries.",
|
|
42840
42846
|
{
|
|
42841
|
-
query_id: external_exports.number().describe("
|
|
42847
|
+
query_id: external_exports.number().describe("ID of the saved query to archive/delete (from list_queries)")
|
|
42842
42848
|
},
|
|
42843
42849
|
{ destructiveHint: true },
|
|
42844
42850
|
async ({ query_id }) => {
|
|
@@ -42854,11 +42860,11 @@ server.tool(
|
|
|
42854
42860
|
);
|
|
42855
42861
|
server.tool(
|
|
42856
42862
|
"list_dashboards",
|
|
42857
|
-
"List dashboards in Redash.",
|
|
42863
|
+
"List dashboards in Redash, most recently updated first. Behavior: returns a paginated array where each item has id, name, slug, and created/updated timestamps. Usage: use this to discover a dashboard's id or slug, then call get_dashboard to inspect its widgets and visualizations, or create_dashboard to make a new one. Supports keyword search and pagination.",
|
|
42858
42864
|
{
|
|
42859
|
-
search: external_exports.string().optional().describe("
|
|
42860
|
-
page: external_exports.number().optional().default(1),
|
|
42861
|
-
page_size: external_exports.number().optional().default(20).describe("
|
|
42865
|
+
search: external_exports.string().optional().describe("Optional keyword to filter dashboards by name"),
|
|
42866
|
+
page: external_exports.number().optional().default(1).describe("Page number to fetch, 1-based (default 1)"),
|
|
42867
|
+
page_size: external_exports.number().optional().default(20).describe("Number of dashboards per page, 1-100 (default 20)")
|
|
42862
42868
|
},
|
|
42863
42869
|
{ readOnlyHint: true },
|
|
42864
42870
|
async ({ search, page, page_size }) => {
|
|
@@ -42888,9 +42894,9 @@ server.tool(
|
|
|
42888
42894
|
);
|
|
42889
42895
|
server.tool(
|
|
42890
42896
|
"get_dashboard",
|
|
42891
|
-
"Get dashboard
|
|
42897
|
+
"Get a dashboard's full layout. Behavior: returns the dashboard's id, name, slug, and every widget, each with its linked visualization (id, name, type) and the query behind it (id, name). Usage: find the dashboard id or slug with list_dashboards; use the returned visualization/query ids to understand or extend the dashboard with add_widget.",
|
|
42892
42898
|
{
|
|
42893
|
-
dashboard_id_or_slug: external_exports.string().describe("Dashboard ID or slug (from list_dashboards)")
|
|
42899
|
+
dashboard_id_or_slug: external_exports.string().describe("Dashboard ID or slug to fetch (from list_dashboards)")
|
|
42894
42900
|
},
|
|
42895
42901
|
{ readOnlyHint: true },
|
|
42896
42902
|
async ({ dashboard_id_or_slug }) => {
|
|
@@ -42916,9 +42922,9 @@ server.tool(
|
|
|
42916
42922
|
);
|
|
42917
42923
|
server.tool(
|
|
42918
42924
|
"create_dashboard",
|
|
42919
|
-
"Create a new dashboard.",
|
|
42925
|
+
"Create a new, empty dashboard. Behavior: creates the dashboard and returns its id, name, and slug. Usage: after creating it, populate it with charts using add_widget, passing visualization ids obtained from get_query. To list or inspect existing dashboards instead, use list_dashboards / get_dashboard.",
|
|
42920
42926
|
{
|
|
42921
|
-
name: external_exports.string().describe("
|
|
42927
|
+
name: external_exports.string().describe("Display name for the new dashboard")
|
|
42922
42928
|
},
|
|
42923
42929
|
{ destructiveHint: true },
|
|
42924
42930
|
async ({ name }) => {
|
|
@@ -42942,12 +42948,12 @@ server.tool(
|
|
|
42942
42948
|
);
|
|
42943
42949
|
server.tool(
|
|
42944
42950
|
"add_widget",
|
|
42945
|
-
"Add a visualization
|
|
42951
|
+
"Add a saved query's visualization onto a dashboard as a widget. Behavior: places the widget and returns its id and dashboard_id. Usage: get the dashboard_id from list_dashboards or create_dashboard, and the visualization_id from get_query (each saved query exposes its visualizations). This is how you build up a dashboard after creating it.",
|
|
42946
42952
|
{
|
|
42947
|
-
dashboard_id: external_exports.number().describe("
|
|
42948
|
-
visualization_id: external_exports.number().describe("
|
|
42949
|
-
text: external_exports.string().optional().default("").describe("
|
|
42950
|
-
width: external_exports.union([external_exports.literal(1), external_exports.literal(2)]).optional().default(1).describe("Widget width
|
|
42953
|
+
dashboard_id: external_exports.number().describe("ID of the dashboard to add the widget to (from list_dashboards/create_dashboard)"),
|
|
42954
|
+
visualization_id: external_exports.number().describe("ID of the visualization to embed (from get_query's visualizations list)"),
|
|
42955
|
+
text: external_exports.string().optional().default("").describe("Optional text/markdown caption shown on the widget"),
|
|
42956
|
+
width: external_exports.union([external_exports.literal(1), external_exports.literal(2)]).optional().default(1).describe("Widget width: 1 = half row, 2 = full row (default 1)")
|
|
42951
42957
|
},
|
|
42952
42958
|
{ destructiveHint: true },
|
|
42953
42959
|
async ({ dashboard_id, visualization_id, text, width }) => {
|
|
@@ -42977,7 +42983,7 @@ server.tool(
|
|
|
42977
42983
|
);
|
|
42978
42984
|
server.tool(
|
|
42979
42985
|
"list_alerts",
|
|
42980
|
-
"List alerts in Redash.",
|
|
42986
|
+
"List all alerts configured in Redash. Behavior: returns an array where each alert has id, name, current state (ok / triggered / unknown), last_triggered_at, its linked query (id, name), and threshold options. Usage: use this to discover alert_ids, then call get_alert for one alert's full detail, or create_alert to add a new one.",
|
|
42981
42987
|
{},
|
|
42982
42988
|
{ readOnlyHint: true },
|
|
42983
42989
|
async () => {
|
|
@@ -43002,9 +43008,9 @@ server.tool(
|
|
|
43002
43008
|
);
|
|
43003
43009
|
server.tool(
|
|
43004
43010
|
"get_alert",
|
|
43005
|
-
"Get alert
|
|
43011
|
+
"Get the full detail of a single alert. Behavior: returns the alert's id, name, current state, last_triggered_at, threshold options (column, operator, value), and the query it monitors (id, name, description, data_source_id). Usage: find the alert_id with list_alerts.",
|
|
43006
43012
|
{
|
|
43007
|
-
alert_id: external_exports.number().describe("
|
|
43013
|
+
alert_id: external_exports.number().describe("ID of the alert to inspect (from list_alerts)")
|
|
43008
43014
|
},
|
|
43009
43015
|
{ readOnlyHint: true },
|
|
43010
43016
|
async ({ alert_id }) => {
|
|
@@ -43033,14 +43039,14 @@ server.tool(
|
|
|
43033
43039
|
);
|
|
43034
43040
|
server.tool(
|
|
43035
43041
|
"create_alert",
|
|
43036
|
-
"Create a
|
|
43042
|
+
"Create an alert that watches a saved query and fires when a chosen result column crosses a threshold (e.g., daily_signups less than 10). Behavior: creates the alert and returns its id and name. Usage: get the query_id from list_queries and confirm the exact column name with get_query / get_query_result first. The alert evaluates the query's latest result on Redash's schedule.",
|
|
43037
43043
|
{
|
|
43038
|
-
name: external_exports.string().describe("
|
|
43039
|
-
query_id: external_exports.number().describe("
|
|
43040
|
-
column: external_exports.string().describe("
|
|
43041
|
-
op: external_exports.enum(["greater than", "less than", "equals"]).describe("Comparison operator"),
|
|
43042
|
-
value: external_exports.number().describe("Threshold value"),
|
|
43043
|
-
rearm: external_exports.number().optional().default(0).describe("
|
|
43044
|
+
name: external_exports.string().describe("Display name for the alert"),
|
|
43045
|
+
query_id: external_exports.number().describe("ID of the saved query whose results are monitored (from list_queries)"),
|
|
43046
|
+
column: external_exports.string().describe("Name of the result column to compare against the threshold"),
|
|
43047
|
+
op: external_exports.enum(["greater than", "less than", "equals"]).describe("Comparison operator between the column value and the threshold"),
|
|
43048
|
+
value: external_exports.number().describe("Threshold value that triggers the alert when the comparison is true"),
|
|
43049
|
+
rearm: external_exports.number().optional().default(0).describe("Seconds to wait before the alert can fire again; 0 means fire only once until manually reset (default 0)")
|
|
43044
43050
|
},
|
|
43045
43051
|
{ destructiveHint: true },
|
|
43046
43052
|
async ({ name, query_id, column, op, value, rearm }) => {
|
package/glama.json
ADDED
package/manifest.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest_version": "0.3",
|
|
3
3
|
"name": "redash-mcp",
|
|
4
|
-
"version": "3.1.
|
|
4
|
+
"version": "3.1.6",
|
|
5
5
|
"description": "MCP server for Redash -- query data, manage dashboards, and run SQL with natural language. 24 tools including BIRD SQL methodology.",
|
|
6
6
|
"long_description": "Connects an MCP client to a Redash instance: list data sources, inspect schemas, run SQL, manage saved queries / dashboards / alerts, and use BIRD SQL helpers (smart_query, keyword maps, few-shot examples, feedback, evaluation). Built-in SQL safety guards flag PII access and expensive scans; safety mode can be tuned per install. **Third-party data flow:** if you also set ANTHROPIC_API_KEY in the shell environment, the BIRD smart_query tool may send table-name lists (never query results or row data) to the Anthropic API as a fallback for table selection. Leave ANTHROPIC_API_KEY unset to disable this entirely.",
|
|
7
7
|
"icon": "icon.png",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "redash-mcp",
|
|
3
3
|
"mcpName": "io.github.seob717/redash-mcp",
|
|
4
|
-
"version": "3.1.
|
|
4
|
+
"version": "3.1.6",
|
|
5
5
|
"description": "MCP server that connects Redash to Claude AI — query data, manage dashboards, and run SQL with natural language, with built-in SQL safety guards.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "seob717",
|