create_feature_flag
Generate and manage feature flags using a defined schema in the GrowthBook MCP Server. Specify ID, value type, default value, and file extension to create flags for controlled feature rollouts.
Instructions
Create, add, or wrap an element with a feature flag.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| archived | No | Whether the feature flag is archived | |
| defaultValue | Yes | The default value of the feature flag | |
| description | No | A description of the feature flag | |
| fileExtension | Yes | The extension of the current file. If it's unclear, ask the user. | |
| id | Yes | A unique key name for the feature | |
| project | No | The project the feature flag belongs to | |
| tags | No | Tags for the feature flag | |
| valueType | Yes | The value type the feature flag will return |
Implementation Reference
- src/tools/features.ts:40-129 (handler)The handler function that executes the create_feature_flag tool: fetches environments, constructs payload, posts to GrowthBook API, handles response, and returns formatted content with links and code stubs.async ({ id, valueType, defaultValue, description, project, fileExtension, }) => { // get environments let environments = []; const defaults = await getDefaults(apiKey, baseApiUrl); if (defaults.environments) { environments = defaults.environments; } else { const envRes = await fetch( `${baseApiUrl}/api/v1/features/environments`, { headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json", }, } ); await handleResNotOk(envRes); const envData = await envRes.json(); environments = envData.environments.map((env: any) => env.id); } const payload = { id, description, owner: user, valueType, defaultValue, tags: ["mcp"], environments: environments.reduce( (acc: Record<string, any>, env: string) => { acc[env] = { enabled: false, rules: [], }; return acc; }, {} ), ...(project && { project }), }; try { const res = await fetch(`${baseApiUrl}/api/v1/features`, { method: "POST", headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json", }, body: JSON.stringify(payload), }); await handleResNotOk(res); const data = await res.json(); const { docs, language, stub } = getDocsMetadata(fileExtension); const linkToGrowthBook = generateLinkToGrowthBook( appOrigin, "features", id ); const text = `This is the API response: ${JSON.stringify(data, null, 2)} Additionally, here is a template of what to show to the user: **✅ Your feature flag \`my-flag-name\` is ready!** [View it in GrowthBook](${linkToGrowthBook}) **How to use it in your code:** (To the LLM agent. Use the text below to properly add the feature flag to the codebase. Also, surface the relevant docs/implemenation to the user) ${stub} **Want to learn more?** See the [GrowthBook ${language} docs](${docs}) `; return { content: [{ type: "text", text }], }; } catch (error) { throw new Error(`Error creating feature flag: ${error}`); } }
- src/tools/features.ts:22-130 (registration)Registers the create_feature_flag tool on the MCP server within registerFeatureTools, specifying name, description, input schema, hints, and handler function./** * Tool: create_feature_flag */ server.tool( "create_feature_flag", "Creates a new feature flag in GrowthBook and modifies the codebase when relevant.", { id: featureFlagSchema.id, valueType: featureFlagSchema.valueType, defaultValue: featureFlagSchema.defaultValue, description: featureFlagSchema.description.optional().default(""), project: featureFlagSchema.project.optional(), fileExtension: featureFlagSchema.fileExtension, }, { readOnlyHint: false, destructiveHint: false, }, async ({ id, valueType, defaultValue, description, project, fileExtension, }) => { // get environments let environments = []; const defaults = await getDefaults(apiKey, baseApiUrl); if (defaults.environments) { environments = defaults.environments; } else { const envRes = await fetch( `${baseApiUrl}/api/v1/features/environments`, { headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json", }, } ); await handleResNotOk(envRes); const envData = await envRes.json(); environments = envData.environments.map((env: any) => env.id); } const payload = { id, description, owner: user, valueType, defaultValue, tags: ["mcp"], environments: environments.reduce( (acc: Record<string, any>, env: string) => { acc[env] = { enabled: false, rules: [], }; return acc; }, {} ), ...(project && { project }), }; try { const res = await fetch(`${baseApiUrl}/api/v1/features`, { method: "POST", headers: { Authorization: `Bearer ${apiKey}`, "Content-Type": "application/json", }, body: JSON.stringify(payload), }); await handleResNotOk(res); const data = await res.json(); const { docs, language, stub } = getDocsMetadata(fileExtension); const linkToGrowthBook = generateLinkToGrowthBook( appOrigin, "features", id ); const text = `This is the API response: ${JSON.stringify(data, null, 2)} Additionally, here is a template of what to show to the user: **✅ Your feature flag \`my-flag-name\` is ready!** [View it in GrowthBook](${linkToGrowthBook}) **How to use it in your code:** (To the LLM agent. Use the text below to properly add the feature flag to the codebase. Also, surface the relevant docs/implemenation to the user) ${stub} **Want to learn more?** See the [GrowthBook ${language} docs](${docs}) `; return { content: [{ type: "text", text }], }; } catch (error) { throw new Error(`Error creating feature flag: ${error}`); } } );
- src/utils.ts:240-263 (schema)Shared Zod schema object defining input parameters for feature flag tools, including id, valueType, defaultValue, etc.export const featureFlagSchema = { id: z .string() .regex( /^[a-zA-Z0-9_.:|_-]+$/, "Feature key can only include letters, numbers, and the characters _, -, ., :, and |" ) .describe("A unique key name for the feature"), valueType: z .enum(["string", "number", "boolean", "json"]) .describe("The value type the feature flag will return"), defaultValue: z.string().describe("The default value of the feature flag"), description: z.string().describe("A brief description of the feature flag"), archived: z.boolean().describe("Whether the feature flag should be archived"), project: z .string() .describe("The ID of the project to which the feature flag belongs"), // Contextual info fileExtension: z .enum(SUPPORTED_FILE_EXTENSIONS) .describe( "The extension of the current file. If it's unclear, ask the user." ), } as const;
- src/index.ts:81-87 (registration)Top-level call to registerFeatureTools in the main MCP server initialization, which includes the create_feature_flag tool.registerFeatureTools({ server, baseApiUrl, apiKey, appOrigin, user, });