Skip to content

Commit 60e57b3

Browse files
committed
Release commit
1 parent 1d37723 commit 60e57b3

9 files changed

Lines changed: 191 additions & 39 deletions

File tree

README.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,44 @@ export METABASE_USERNAME=your_username
7575
export METABASE_PASSWORD=your_password
7676
```
7777

78+
### Optional Arguments
79+
80+
The server supports command-line arguments to customize tool loading:
81+
82+
- **`--essential`** (default): Load only essential tools
83+
- **`--all`**: Load all 80+ available tools
84+
- **`--write`**: Load only write/modification tools
85+
- **`--read`**: Load only read-only tools
86+
87+
```bash
88+
# Using published package (recommended)
89+
# Default behavior (essential tools only)
90+
npx @windsurf-public/mcp-metabase-server
91+
92+
# Load all tools
93+
npx @windsurf-public/mcp-metabase-server --all
94+
95+
# Load only write tools
96+
npx @windsurf-public/mcp-metabase-server --write
97+
98+
# Load only read-only tools
99+
npx @windsurf-public/mcp-metabase-server --read
100+
101+
# Using local development build
102+
npm run build
103+
node dist/server.js # Default (essential tools)
104+
node dist/server.js --all # All tools
105+
node dist/server.js --write # Write tools only
106+
node dist/server.js --read # Read-only tools only
107+
```
108+
78109
## 🔌 Integration Examples
79110

80111
### Claude Desktop
81112

82113
Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
83114

115+
**Using published package:**
84116
```json
85117
{
86118
"mcpServers": {
@@ -96,10 +128,43 @@ Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_
96128
}
97129
```
98130

131+
**Using local development build:**
132+
```json
133+
{
134+
"mcpServers": {
135+
"metabase": {
136+
"command": "node",
137+
"args": ["/path/to/metabase-mcp-server/dist/server.js"],
138+
"env": {
139+
"METABASE_URL": "https://your-metabase-instance.com",
140+
"METABASE_API_KEY": "your_metabase_api_key"
141+
}
142+
}
143+
}
144+
}
145+
```
146+
147+
**With custom flags:**
148+
```json
149+
{
150+
"mcpServers": {
151+
"metabase-all": {
152+
"command": "npx",
153+
"args": ["@windsurf-public/mcp-metabase-server", "--all"],
154+
"env": {
155+
"METABASE_URL": "https://your-metabase-instance.com",
156+
"METABASE_API_KEY": "your_metabase_api_key"
157+
}
158+
}
159+
}
160+
}
161+
```
162+
99163
### Windsurf IDE
100164

101165
Add to your Windsurf MCP config (`~/.windsurf/mcp_config.json`):
102166

167+
**Using published package:**
103168
```json
104169
{
105170
"mcpServers": {
@@ -115,6 +180,46 @@ Add to your Windsurf MCP config (`~/.windsurf/mcp_config.json`):
115180
}
116181
```
117182

183+
**Using local development build:**
184+
```json
185+
{
186+
"mcpServers": {
187+
"metabase": {
188+
"command": "node",
189+
"args": ["/path/to/metabase-mcp-server/dist/server.js"],
190+
"env": {
191+
"METABASE_URL": "https://your-metabase-instance.com",
192+
"METABASE_API_KEY": "your_metabase_api_key"
193+
}
194+
}
195+
}
196+
}
197+
```
198+
199+
**With custom flags:**
200+
```json
201+
{
202+
"mcpServers": {
203+
"metabase-read": {
204+
"command": "npx",
205+
"args": ["@windsurf-public/mcp-metabase-server", "--read"],
206+
"env": {
207+
"METABASE_URL": "https://your-metabase-instance.com",
208+
"METABASE_API_KEY": "your_metabase_api_key"
209+
}
210+
},
211+
"metabase-write": {
212+
"command": "npx",
213+
"args": ["@windsurf-public/mcp-metabase-server", "--write"],
214+
"env": {
215+
"METABASE_URL": "https://your-metabase-instance.com",
216+
"METABASE_API_KEY": "your_metabase_api_key"
217+
}
218+
}
219+
}
220+
}
221+
```
222+
118223
## 🛠️ Available Tools
119224

120225
<details>

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@windsurf-public/mcp-metabase-server",
3-
"version": "1.0.6",
3+
"version": "1.0.7",
44
"description": "A Model Context Protocol server for Metabase integration",
55
"author": "Cognition <devin@cognition.ai>",
66
"license": "MIT",

src/server.ts

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,25 @@ const server = new FastMCP({
3131
const originalAddTool = server.addTool.bind(server);
3232
server.addTool = function(toolConfig: any) {
3333
const { metadata = {}, ...restConfig } = toolConfig;
34-
const { isWrite, isEssential } = metadata;
34+
const { isWrite, isEssential, isRead } = metadata;
3535

36-
// Skip non-essential tools when essential mode is enabled
37-
if (filterOptions.essentialOnly && !isEssential) {
38-
return;
39-
}
40-
41-
// Skip non-write tools when write mode is disabled
42-
if (filterOptions.writeMode && !isWrite) {
43-
return;
36+
// Apply filtering based on selected mode
37+
switch (filterOptions.mode) {
38+
case 'essential':
39+
// Only load essential tools
40+
if (!isEssential) return;
41+
break;
42+
case 'write':
43+
// Only load write tools
44+
if (!isWrite) return;
45+
break;
46+
case 'read':
47+
// Only load read-only tools
48+
if (!isRead) return;
49+
break;
50+
case 'all':
51+
// Load all tools - no filtering
52+
break;
4453
}
4554

4655
// Register the tool
@@ -58,11 +67,21 @@ addAdditionalTools(server, metabaseClient);
5867
addMetabaseResources(server, metabaseClient);
5968

6069
// Log filtering status
61-
if (filterOptions.essentialOnly) {
62-
console.error(`INFO: Essential mode enabled`);
63-
}
64-
if (filterOptions.writeMode) {
65-
console.error(`INFO: Write operations enabled`);
70+
console.error(`INFO: Tool filtering mode: ${filterOptions.mode} ${filterOptions.mode === 'essential' ? '(default)' : ''}`);
71+
72+
switch (filterOptions.mode) {
73+
case 'essential':
74+
console.error(`INFO: Only essential tools loaded. Use --all to load all tools.`);
75+
break;
76+
case 'write':
77+
console.error(`INFO: Only write/modification tools loaded.`);
78+
break;
79+
case 'read':
80+
console.error(`INFO: Only read-only tools loaded.`);
81+
break;
82+
case 'all':
83+
console.error(`INFO: All tools loaded.`);
84+
break;
6685
}
6786

6887
// Start the server

src/tools/additional-tools.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export function addAdditionalTools(server: any, metabaseClient: MetabaseClient)
1616
server.addTool({
1717
name: "get_collection_items",
1818
description: "Retrieve all items (cards, dashboards) within a Metabase collection - use this to explore collection contents, organize analytical assets, or understand content structure",
19-
metadata: { isEssential: true },
19+
metadata: { isEssential: true, isRead: true },
2020
parameters: z.object({
2121
collection_id: z.number().describe("Collection ID"),
2222
}),
@@ -97,7 +97,7 @@ export function addAdditionalTools(server: any, metabaseClient: MetabaseClient)
9797
server.addTool({
9898
name: "search_content",
9999
description: "Search across all Metabase content including cards, dashboards, collections, and models - use this to find specific content, discover assets, or explore analytical resources",
100-
metadata: { isEssential: true },
100+
metadata: { isEssential: true, isRead: true },
101101
parameters: z
102102
.object({
103103
q: z.string().min(1).describe("Search query"),
@@ -137,7 +137,7 @@ export function addAdditionalTools(server: any, metabaseClient: MetabaseClient)
137137
server.addTool({
138138
name: "list_collections",
139139
description: "Retrieve all Metabase collections for organizing analytical content - use this to understand content structure, find collections, or explore organizational hierarchy",
140-
metadata: { isEssential: true },
140+
metadata: { isEssential: true, isRead: true },
141141
parameters: z.object({
142142
archived: z.boolean().optional().default(false).describe("Include archived collections"),
143143
}),
@@ -264,7 +264,7 @@ export function addAdditionalTools(server: any, metabaseClient: MetabaseClient)
264264
server.addTool({
265265
name: "list_users",
266266
description: "Retrieve all Metabase users with their roles and permissions - use this to understand user access, manage permissions, or audit accounts",
267-
metadata: { isEssential: true },
267+
metadata: { isEssential: true, isRead: true },
268268
parameters: z.object({
269269
include_deactivated: z.boolean().optional().default(false).describe("Include deactivated users"),
270270
}),

src/tools/card-tools.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export function addCardTools(server: any, metabaseClient: MetabaseClient) {
1717
server.addTool({
1818
name: "list_cards",
1919
description: "Retrieve all Metabase cards with optional filtering by source type (e.g., 'models') or model relationships - use this to discover available cards, find specific cards by type, or get an overview of all analytical content",
20-
metadata: { isEssential: true },
20+
metadata: { isEssential: true, isRead: true },
2121
parameters: z.object({
2222
f: z.string().optional().describe("Filter by source (e.g., 'models')"),
2323
model_id: z.number().optional().describe("Filter by model_id"),
@@ -47,6 +47,7 @@ export function addCardTools(server: any, metabaseClient: MetabaseClient) {
4747
server.addTool({
4848
name: "get_card",
4949
description: "Get complete metadata and configuration for a specific Metabase card including query definition, visualization settings, collection location, and permissions - use this when you need to examine or understand how a particular card is built",
50+
metadata: { isEssential: true, isRead: true },
5051
parameters: z.object({
5152
card_id: z.number().describe("Card ID"),
5253
}),
@@ -258,6 +259,7 @@ export function addCardTools(server: any, metabaseClient: MetabaseClient) {
258259
server.addTool({
259260
name: "export_card_result",
260261
description: "Execute a Metabase card and export the results in a specific format (CSV, Excel, JSON, etc.) - use this to download data for external analysis, create reports for stakeholders, or integrate query results with other systems",
262+
metadata: { isEssential: true },
261263
parameters: z.object({
262264
card_id: z.number().describe("Card ID"),
263265
export_format: z.string().describe("Export format (e.g., csv, xlsx, json)"),
@@ -329,7 +331,7 @@ export function addCardTools(server: any, metabaseClient: MetabaseClient) {
329331
server.addTool({
330332
name: "get_card_dashboards",
331333
description: "Find all dashboards that include a specific Metabase card - use this to understand where a card is being used, track dependencies before making changes, or find related analytical content",
332-
metadata: { isEssential: true },
334+
metadata: { isEssential: true, isRead: true },
333335
parameters: z.object({
334336
card_id: z.number().describe("Card ID"),
335337
}),
@@ -359,6 +361,7 @@ export function addCardTools(server: any, metabaseClient: MetabaseClient) {
359361
server.addTool({
360362
name: "list_embeddable_cards",
361363
description: "Retrieve all Metabase cards configured for embedding in external applications (requires admin privileges) - use this to audit embedded content, manage external integrations, or review public-facing analytics",
364+
metadata: { isRead: true },
362365
execute: async () => {
363366
try {
364367
const result = await metabaseClient.getEmbeddableCards();
@@ -445,6 +448,7 @@ export function addCardTools(server: any, metabaseClient: MetabaseClient) {
445448
server.addTool({
446449
name: "list_public_cards",
447450
description: "Retrieve all Metabase cards that have public URLs enabled (requires admin privileges) - use this to audit publicly accessible content, review security settings, or manage external data sharing",
451+
metadata: { isRead: true },
448452
execute: async () => {
449453
try {
450454
const result = await metabaseClient.getPublicCards();
@@ -587,6 +591,7 @@ export function addCardTools(server: any, metabaseClient: MetabaseClient) {
587591
server.addTool({
588592
name: "get_card_param_values",
589593
description: "Retrieve all available values for a specific parameter in a Metabase card - use this to populate dropdown filters, validate parameter inputs, or understand what data options are available for interactive cards",
594+
metadata: { isRead: true },
590595
parameters: z.object({
591596
card_id: z.number().describe("Card ID"),
592597
param_key: z.string().describe("Parameter key"),
@@ -623,6 +628,7 @@ export function addCardTools(server: any, metabaseClient: MetabaseClient) {
623628
server.addTool({
624629
name: "search_card_param_values",
625630
description: "Search and filter available parameter values for a Metabase card using a text query - use this to find specific parameter options in large datasets, help users locate filter values, or implement autocomplete functionality",
631+
metadata: { isRead: true },
626632
parameters: z.object({
627633
card_id: z.number().describe("Card ID"),
628634
param_key: z.string().describe("Parameter key"),

0 commit comments

Comments
 (0)