Skip to main content
Glama
bucketeer-io

Bucketeer MCP Server

Official
by bucketeer-io

createFeatureFlag

Create a new feature flag in a specified environment to control feature releases and user experiences through configurable variations.

Instructions

Create a new feature flag in the specified environment

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
idYesUnique identifier for the feature flag (alphanumeric, hyphens, underscores)
nameYesHuman-readable name for the feature flag
descriptionNoDescription of the feature flag
environmentIdNoEnvironment ID (uses default if not provided)
variationsYesList of variations (at least 2 required)
tagsNoTags for the feature flag
defaultOnVariationIndexYesIndex of the variation to serve when flag is on (0-based)
defaultOffVariationIndexYesIndex of the variation to serve when flag is off (0-based)
variationTypeNoType of the variation values (default: STRING)

Implementation Reference

  • The handler function that executes the createFeatureFlag tool logic: validates input with Zod schema, checks variation indices, creates BucketeerClient, sends createFeature request to API, logs success/error, returns MCP-formatted response.
    handler: async (input: unknown) => {
    	try {
    		// Validate input
    		const params = createFlagSchema.parse(input);
    
    		// Validate variation indices
    		if (params.defaultOnVariationIndex >= params.variations.length) {
    			throw new Error(
    				`defaultOnVariationIndex ${params.defaultOnVariationIndex} is out of bounds. Must be less than ${params.variations.length}`,
    			);
    		}
    		if (params.defaultOffVariationIndex >= params.variations.length) {
    			throw new Error(
    				`defaultOffVariationIndex ${params.defaultOffVariationIndex} is out of bounds. Must be less than ${params.variations.length}`,
    			);
    		}
    
    		logger.debug("Creating feature flag", params);
    
    		// Create API client
    		const client = new BucketeerClient(
    			config.bucketeerHost,
    			config.bucketeerApiKey,
    		);
    
    		// Prepare request
    		const request: CreateFeatureRequest = {
    			id: params.id,
    			name: params.name,
    			description: params.description,
    			environmentId: getEnvironmentId(params.environmentId),
    			variations: params.variations,
    			tags: params.tags,
    			defaultOnVariationIndex: params.defaultOnVariationIndex,
    			defaultOffVariationIndex: params.defaultOffVariationIndex,
    			variationType: params.variationType,
    		};
    
    		// Make API call
    		const response = await client.createFeature(request);
    
    		logger.info(`Successfully created feature flag: ${response.feature.id}`);
    
    		return {
    			content: [
    				{
    					type: "text",
    					text: JSON.stringify(
    						{
    							success: true,
    							feature: response.feature,
    						},
    						null,
    						2,
    					),
    				},
    			],
    		};
    	} catch (error) {
    		logger.error("Failed to create feature flag", error);
    
    		if (error instanceof z.ZodError) {
    			return {
    				content: [
    					{
    						type: "text",
    						text: JSON.stringify(
    							{
    								success: false,
    								error: "Invalid input parameters",
    								details: error.issues,
    							},
    							null,
    							2,
    						),
    					},
    				],
    				isError: true,
    			};
    		}
    
    		return {
    			content: [
    				{
    					type: "text",
    					text: JSON.stringify(
    						{
    							success: false,
    							error: error instanceof Error ? error.message : "Unknown error",
    						},
    						null,
    						2,
    					),
    				},
    			],
    			isError: true,
    		};
    	}
    },
  • Zod schema (createFlagSchema) used internally by the handler for input validation of the createFeatureFlag tool.
    export const createFlagSchema = z.object({
    	id: z
    		.string()
    		.min(1, "Feature flag ID is required")
    		.regex(
    			/^[a-zA-Z0-9-_]+$/,
    			"ID must contain only alphanumeric characters, hyphens, and underscores",
    		),
    	name: z.string().min(1, "Feature flag name is required"),
    	description: z.string().optional().default(""),
    	environmentId: z.string().optional(),
    	variations: z
    		.array(variationSchema)
    		.min(2, "At least 2 variations are required"),
    	tags: z.array(z.string()).optional(),
    	defaultOnVariationIndex: z.number().min(0),
    	defaultOffVariationIndex: z.number().min(0),
    	variationType: z
    		.nativeEnum(VariationType)
    		.optional()
    		.default(VariationType.STRING),
    });
  • JSON Schema (inputSchema) defining the input structure for the 'createFeatureFlag' tool, exposed to the MCP client.
    inputSchema: {
    	type: "object" as const,
    	properties: {
    		id: {
    			type: "string",
    			description:
    				"Unique identifier for the feature flag (alphanumeric, hyphens, underscores)",
    		},
    		name: {
    			type: "string",
    			description: "Human-readable name for the feature flag",
    		},
    		description: {
    			type: "string",
    			description: "Description of the feature flag",
    		},
    		environmentId: {
    			type: "string",
    			description: "Environment ID (uses default if not provided)",
    		},
    		variations: {
    			type: "array",
    			description: "List of variations (at least 2 required)",
    			items: {
    				type: "object",
    				properties: {
    					value: {
    						type: "string",
    						description: "The value returned when this variation is served",
    					},
    					name: {
    						type: "string",
    						description: "Name of the variation",
    					},
    					description: {
    						type: "string",
    						description: "Description of the variation",
    					},
    				},
    				required: ["value", "name"],
    			},
    		},
    		tags: {
    			type: "array",
    			items: { type: "string" },
    			description: "Tags for the feature flag",
    		},
    		defaultOnVariationIndex: {
    			type: "number",
    			description:
    				"Index of the variation to serve when flag is on (0-based)",
    		},
    		defaultOffVariationIndex: {
    			type: "number",
    			description:
    				"Index of the variation to serve when flag is off (0-based)",
    		},
    		variationType: {
    			type: "string",
    			enum: ["STRING", "BOOLEAN", "NUMBER", "JSON"],
    			description: "Type of the variation values (default: STRING)",
    		},
    	},
    	required: [
    		"id",
    		"name",
    		"variations",
    		"defaultOnVariationIndex",
    		"defaultOffVariationIndex",
    	],
    },
  • Registration of the createFlagTool (named 'createFeatureFlag') in the central tools array, imported into the MCP server.
    export const tools = [
    	listFlagsTool,
    	createFlagTool,
    	getFlagTool,
    	updateFlagTool,
    	archiveFlagTool,
    ];
  • src/server.ts:8-65 (registration)
    MCP server setup in BucketeerMCPServer: imports tools array and registers ListTools and CallTool request handlers that use the tools list to expose and execute 'createFeatureFlag'.
    import { tools } from "./tools/index.js";
    
    export class BucketeerMCPServer {
    	private server: Server;
    
    	constructor() {
    		this.server = new Server(
    			{
    				name: "bucketeer-mcp-server",
    				version: "1.0.0",
    			},
    			{
    				capabilities: {
    					tools: {},
    				},
    			},
    		);
    
    		this.setupHandlers();
    		this.setupErrorHandling();
    	}
    
    	private setupHandlers() {
    		// Handle list tools request
    		this.server.setRequestHandler(ListToolsRequestSchema, async () => {
    			logger.debug("Listing available tools");
    
    			return {
    				tools: tools.map((tool) => ({
    					name: tool.name,
    					description: tool.description,
    					inputSchema: tool.inputSchema,
    				})),
    			};
    		});
    
    		// Handle tool calls
    		this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
    			const { name, arguments: args } = request.params;
    
    			logger.info(`Tool called: ${name}`, { arguments: args });
    
    			const tool = tools.find((t) => t.name === name);
    
    			if (!tool) {
    				logger.error(`Tool not found: ${name}`);
    				throw new Error(`Tool not found: ${name}`);
    			}
    
    			try {
    				const result = await tool.handler(args);
    				logger.info(`Tool ${name} executed successfully`);
    				return result;
    			} catch (error) {
    				logger.error(`Tool ${name} execution failed`, error);
    				throw error;
    			}
    		});
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden but only states the basic action without behavioral details. It doesn't mention permissions required, whether creation is idempotent, rate limits, error conditions, or what happens on success (e.g., returns the created flag). For a mutation tool, this is a significant gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that states the core purpose without unnecessary words. It's appropriately sized and front-loaded with the essential information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a creation tool with 9 parameters, no annotations, and no output schema, the description is inadequate. It doesn't explain the creation workflow, what 'create' entails (e.g., validation rules beyond schema), or what the tool returns. The schema handles parameter details, but behavioral context is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, providing detailed parameter documentation. The description adds no parameter-specific information beyond implying 'environmentId' is optional (uses default), which is already covered in the schema. Baseline 3 is appropriate when schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('create') and resource ('feature flag') with the specific context 'in the specified environment'. It distinguishes from siblings like 'updateFeatureFlag' or 'getFeatureFlag' by specifying it's for creation, though it doesn't explicitly contrast with all siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus alternatives like 'updateFeatureFlag' for modifications or 'archiveFeatureFlag' for removal. The description mentions 'specified environment' but doesn't explain when environment selection matters or what happens if omitted.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/bucketeer-io/bucketeer-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server