@growthbook/mcp 1.8.0 → 1.8.1

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@growthbook/mcp",
3
3
  "mcpName": "io.github.growthbook/growthbook-mcp",
4
- "version": "1.8.0",
4
+ "version": "1.8.1",
5
5
  "description": "MCP Server for interacting with GrowthBook",
6
6
  "access": "public",
7
7
  "homepage": "https://github.com/growthbook/growthbook-mcp",
@@ -140,7 +140,7 @@ export function registerFeatureTools({ server, baseApiUrl, apiKey, appOrigin, us
140
140
  */
141
141
  server.registerTool("get_feature_flags", {
142
142
  title: "Get Feature Flags",
143
- description: "Lists feature flags in your GrowthBook organization, or fetches details for a specific flag by ID. Use to find existing flags before creating new ones, get a flag's current configuration and rules, or find flag IDs needed for create_force_rule or create_experiment. Single flag fetch (via featureFlagId) returns full config including environment rules. If flag is archived, suggest removing from codebase.",
143
+ description: "Lists feature flags with full details (rules, environments, values) or fetches a single flag by ID. Returns up to 100 flags per page. Use to inspect flag configuration, rules, and status. For a lightweight list of all flag IDs (no limit), use list_feature_keys instead.",
144
144
  inputSchema: z.object({
145
145
  project: featureFlagSchema.project.optional(),
146
146
  featureFlagId: featureFlagSchema.id.optional(),
@@ -188,17 +188,57 @@ export function registerFeatureTools({ server, baseApiUrl, apiKey, appOrigin, us
188
188
  ]));
189
189
  }
190
190
  });
191
+ /**
192
+ * Tool: list_feature_keys
193
+ */
194
+ server.registerTool("list_feature_keys", {
195
+ title: "List Feature Keys",
196
+ description: "Returns all feature flag IDs (keys only, no details) in your GrowthBook organization. Useful for discovering flag IDs when you need to check a large number of flags — for example, before calling get_stale_feature_flags. Optionally filter by project.",
197
+ inputSchema: z.object({
198
+ projectId: z
199
+ .string()
200
+ .optional()
201
+ .describe("Filter by project ID to only return flags in that project."),
202
+ }),
203
+ annotations: {
204
+ readOnlyHint: true,
205
+ },
206
+ }, async ({ projectId }) => {
207
+ try {
208
+ const queryParams = projectId
209
+ ? `?projectId=${encodeURIComponent(projectId)}`
210
+ : "";
211
+ const res = await fetchWithRateLimit(`${baseApiUrl}/api/v1/feature-keys${queryParams}`, {
212
+ headers: buildHeaders(apiKey),
213
+ });
214
+ await handleResNotOk(res);
215
+ const keys = (await res.json());
216
+ return {
217
+ content: [
218
+ {
219
+ type: "text",
220
+ text: `**${keys.length} feature flag(s) found${projectId ? ` in project \`${projectId}\`` : ""}:**\n\n${keys.map((k) => `\`${k}\``).join(", ")}`,
221
+ },
222
+ ],
223
+ };
224
+ }
225
+ catch (error) {
226
+ throw new Error(formatApiError(error, "fetching feature keys", [
227
+ "Check that your GB_API_KEY has permission to read features.",
228
+ ]));
229
+ }
230
+ });
191
231
  /**
192
232
  * Tool: get_stale_feature_flags
193
233
  */
194
234
  server.registerTool("get_stale_feature_flags", {
195
235
  title: "Get Stale Feature Flags",
196
- description: "Given a list of feature flag IDs, checks whether each one is stale and returns cleanup guidance including replacement values and SDK search patterns. You MUST provide featureIds — gather them first from the user, from the current file context, or by using the get_feature_flags tool to list all flags and then searching the codebase for those flag IDs to determine which are present.",
236
+ description: "Given a list of feature flag IDs, checks whether each one is stale and returns cleanup guidance including replacement values and SDK search patterns. You MUST provide featureIds — gather them first from the user, from the current file context, or by using list_feature_keys to get all flag IDs and then searching the codebase for those IDs to determine which are present.",
197
237
  inputSchema: z.object({
198
238
  featureIds: z
199
239
  .array(z.string())
200
240
  .optional()
201
- .describe("REQUIRED. One or more feature flag IDs to check (e.g. [\"my-feature\", \"dark-mode\"]). Gather IDs first from the user, from code context, or by using get_feature_flags to list flags and searching the codebase for those IDs."),
241
+ .describe("REQUIRED. One or more feature flag IDs to check (e.g. [\"my-feature\", \"dark-mode\"]). Gather IDs first from the user, from code context, or by using list_feature_keys to get all flag IDs and searching the codebase for those IDs."),
202
242
  }),
203
243
  annotations: {
204
244
  readOnlyHint: true,
@@ -216,7 +256,7 @@ export function registerFeatureTools({ server, baseApiUrl, apiKey, appOrigin, us
216
256
  "To gather feature flag IDs, try one of these approaches:",
217
257
  "1. **Ask the user** which flags they want to check",
218
258
  "2. **Extract from current file context** — look for flag IDs in the open file",
219
- "3. **Use the `get_feature_flags` tool** to list all flags, then search the codebase for those flag IDs to determine which are present",
259
+ "3. **Use the `list_feature_keys` tool** to get all flag IDs, then search the codebase for those IDs to determine which are present",
220
260
  "",
221
261
  "Then call this tool again with the discovered flag IDs.",
222
262
  ].join("\n"),