Skip to main content
Glama

bitbucket_pipelines

Control, trigger, stop, and monitor Bitbucket Pipelines CI/CD. Manage pipeline variables and enable/disable pipelines.

Instructions

Manage Bitbucket Pipelines CI/CD. Actions:

  • list: List pipelines in a repository

  • get: Get details of a specific pipeline

  • trigger: Trigger a new pipeline run on a branch

  • trigger_custom: Trigger a custom pipeline with a specific pattern

  • stop: Stop a running pipeline

  • list_steps: List steps of a pipeline

  • get_step: Get details of a specific step

  • get_logs: Get logs for a pipeline step

  • get_config: Get pipeline configuration (enabled status)

  • set_enabled: Enable or disable pipelines for a repository

  • list_variables: List pipeline variables

  • get_variable: Get a specific pipeline variable

  • create_variable: Create a pipeline variable

  • update_variable: Update a pipeline variable

  • delete_variable: Delete a pipeline variable

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
actionYesAction to perform
workspaceNoWorkspace slug (uses BITBUCKET_WORKSPACE env if omitted)
repo_slugYesRepository slug
pipeline_uuidNoPipeline UUID
step_uuidNoStep UUID
branch_nameNoBranch name to trigger pipeline on (required for trigger/trigger_custom)
patternNoCustom pipeline pattern (for trigger_custom)
variablesNoPipeline variables for trigger
enabledNoEnable or disable pipelines
variable_uuidNoVariable UUID
keyNoVariable key
valueNoVariable value
securedNoWhether variable is secured
sortNoSort field
target_branchNoFilter by target branch
pageNoPage number for pagination
pagelenNoResults per page (default: 25, max 100)
formatNoOutput format: json (full), toon (compact tokens), compact (essential fields only)

Implementation Reference

  • src/server.ts:90-91 (registration)
    Registration of the bitbucket_pipelines tool via registerPipelineTools() call in the BitbucketMCPServer class
    // Pipeline tools (1 tool with 15 actions)
    registerPipelineTools(this.server, this.client, this.config);
  • Handler function registerPipelineTools that registers the 'bitbucket_pipelines' MCP tool with 15 actions (list, get, trigger, trigger_custom, stop, list_steps, get_step, get_logs, get_config, set_enabled, list_variables, get_variable, create_variable, update_variable, delete_variable) using Zod schema validation
    export function registerPipelineTools(
      server: McpServer,
      client: BitbucketClient,
      config: Config
    ): void {
      const pipelinesApi = new PipelinesAPI(client);
    
      server.tool(
        'bitbucket_pipelines',
        `Manage Bitbucket Pipelines CI/CD. Actions:
    - list: List pipelines in a repository
    - get: Get details of a specific pipeline
    - trigger: Trigger a new pipeline run on a branch
    - trigger_custom: Trigger a custom pipeline with a specific pattern
    - stop: Stop a running pipeline
    - list_steps: List steps of a pipeline
    - get_step: Get details of a specific step
    - get_logs: Get logs for a pipeline step
    - get_config: Get pipeline configuration (enabled status)
    - set_enabled: Enable or disable pipelines for a repository
    - list_variables: List pipeline variables
    - get_variable: Get a specific pipeline variable
    - create_variable: Create a pipeline variable
    - update_variable: Update a pipeline variable
    - delete_variable: Delete a pipeline variable`,
        {
          action: z
            .enum([
              'list',
              'get',
              'trigger',
              'trigger_custom',
              'stop',
              'list_steps',
              'get_step',
              'get_logs',
              'get_config',
              'set_enabled',
              'list_variables',
              'get_variable',
              'create_variable',
              'update_variable',
              'delete_variable',
            ])
            .describe('Action to perform'),
          workspace: z
            .string()
            .optional()
            .describe('Workspace slug (uses BITBUCKET_WORKSPACE env if omitted)'),
          repo_slug: z.string().describe('Repository slug'),
          // For get/stop/list_steps actions
          pipeline_uuid: z.string().optional().describe('Pipeline UUID'),
          // For get_step/get_logs actions
          step_uuid: z.string().optional().describe('Step UUID'),
          // For trigger actions
          branch_name: z
            .string()
            .optional()
            .describe('Branch name to trigger pipeline on (required for trigger/trigger_custom)'),
          pattern: z.string().optional().describe('Custom pipeline pattern (for trigger_custom)'),
          variables: z
            .array(
              z.object({
                key: z.string(),
                value: z.string(),
                secured: z.boolean().optional(),
              })
            )
            .optional()
            .describe('Pipeline variables for trigger'),
          // For set_enabled action
          enabled: z.boolean().optional().describe('Enable or disable pipelines'),
          // For variable actions
          variable_uuid: z.string().optional().describe('Variable UUID'),
          key: z.string().optional().describe('Variable key'),
          value: z.string().optional().describe('Variable value'),
          secured: z.boolean().optional().describe('Whether variable is secured'),
          // For list action
          sort: z.string().optional().describe('Sort field'),
          target_branch: z.string().optional().describe('Filter by target branch'),
          // Pagination
          page: z.number().optional().describe('Page number for pagination'),
          pagelen: z.number().optional().describe('Results per page (default: 25, max 100)'),
          // Output format
          format: z
            .enum(['json', 'toon', 'compact'])
            .optional()
            .describe(
              'Output format: json (full), toon (compact tokens), compact (essential fields only)'
            ),
        },
        async (params) => {
          const workspace = params.workspace || config.workspace;
          if (!workspace) {
            return {
              content: [
                {
                  type: 'text' as const,
                  text: 'Error: workspace is required (provide it or set BITBUCKET_WORKSPACE env)',
                },
              ],
              isError: true,
            };
          }
          const { action, repo_slug } = params;
          const format = (params.format ?? config.outputFormat) as OutputFormat;
    
          try {
            switch (action) {
              case 'list': {
                const result = await pipelinesApi.list(workspace, repo_slug, {
                  sort: params.sort,
                  'target.branch': params.target_branch,
                  page: params.page,
                  pagelen: params.pagelen,
                });
                return {
                  content: [
                    {
                      type: 'text' as const,
                      text: formatOutput(paginateResult(result), format, PIPELINE_COMPACT_FIELDS),
                    },
                  ],
                };
              }
    
              case 'get': {
                if (!params.pipeline_uuid) {
                  return {
                    content: [
                      {
                        type: 'text' as const,
                        text: 'Error: pipeline_uuid is required for get action',
                      },
                    ],
                    isError: true,
                  };
                }
                const result = await pipelinesApi.get(workspace, repo_slug, params.pipeline_uuid);
                return {
                  content: [
                    {
                      type: 'text' as const,
                      text: formatOutput(result, format, PIPELINE_COMPACT_FIELDS),
                    },
                  ],
                };
              }
    
              case 'trigger': {
                if (!params.branch_name) {
                  return {
                    content: [
                      {
                        type: 'text' as const,
                        text: 'Error: branch_name is required for trigger action',
                      },
                    ],
                    isError: true,
                  };
                }
                const result = await pipelinesApi.triggerBranch(
                  workspace,
                  repo_slug,
                  params.branch_name,
                  params.variables
                );
                return {
                  content: [
                    {
                      type: 'text' as const,
                      text: formatOutput(result, format, PIPELINE_COMPACT_FIELDS),
                    },
                  ],
                };
              }
    
              case 'trigger_custom': {
                if (!params.branch_name || !params.pattern) {
                  return {
                    content: [
                      {
                        type: 'text' as const,
                        text: 'Error: branch_name and pattern are required for trigger_custom action',
                      },
                    ],
                    isError: true,
                  };
                }
                const result = await pipelinesApi.triggerCustom(
                  workspace,
                  repo_slug,
                  params.branch_name,
                  params.pattern,
                  params.variables
                );
                return {
                  content: [
                    {
                      type: 'text' as const,
                      text: formatOutput(result, format, PIPELINE_COMPACT_FIELDS),
                    },
                  ],
                };
              }
    
              case 'stop': {
                if (!params.pipeline_uuid) {
                  return {
                    content: [
                      {
                        type: 'text' as const,
                        text: 'Error: pipeline_uuid is required for stop action',
                      },
                    ],
                    isError: true,
                  };
                }
                await pipelinesApi.stop(workspace, repo_slug, params.pipeline_uuid);
                return {
                  content: [{ type: 'text' as const, text: 'Pipeline stopped successfully' }],
                };
              }
    
              case 'list_steps': {
                if (!params.pipeline_uuid) {
                  return {
                    content: [
                      {
                        type: 'text' as const,
                        text: 'Error: pipeline_uuid is required for list_steps action',
                      },
                    ],
                    isError: true,
                  };
                }
                const result = await pipelinesApi.listSteps(
                  workspace,
                  repo_slug,
                  params.pipeline_uuid,
                  {
                    page: params.page,
                    pagelen: params.pagelen,
                  }
                );
                return {
                  content: [
                    {
                      type: 'text' as const,
                      text: formatOutput(paginateResult(result), format, PIPELINE_STEP_COMPACT_FIELDS),
                    },
                  ],
                };
              }
    
              case 'get_step': {
                if (!params.pipeline_uuid || !params.step_uuid) {
                  return {
                    content: [
                      {
                        type: 'text' as const,
                        text: 'Error: pipeline_uuid and step_uuid are required for get_step action',
                      },
                    ],
                    isError: true,
                  };
                }
                const result = await pipelinesApi.getStep(
                  workspace,
                  repo_slug,
                  params.pipeline_uuid,
                  params.step_uuid
                );
                return {
                  content: [
                    {
                      type: 'text' as const,
                      text: formatOutput(result, format, PIPELINE_STEP_COMPACT_FIELDS),
                    },
                  ],
                };
              }
    
              case 'get_logs': {
                if (!params.pipeline_uuid || !params.step_uuid) {
                  return {
                    content: [
                      {
                        type: 'text' as const,
                        text: 'Error: pipeline_uuid and step_uuid are required for get_logs action',
                      },
                    ],
                    isError: true,
                  };
                }
                const result = await pipelinesApi.getStepLogs(
                  workspace,
                  repo_slug,
                  params.pipeline_uuid,
                  params.step_uuid
                );
                return {
                  content: [{ type: 'text' as const, text: result }],
                };
              }
    
              case 'get_config': {
                const result = await pipelinesApi.getConfig(workspace, repo_slug);
                return {
                  content: [{ type: 'text' as const, text: formatOutput(result, format) }],
                };
              }
    
              case 'set_enabled': {
                if (params.enabled === undefined) {
                  return {
                    content: [
                      {
                        type: 'text' as const,
                        text: 'Error: enabled is required for set_enabled action',
                      },
                    ],
                    isError: true,
                  };
                }
                await pipelinesApi.setEnabled(workspace, repo_slug, params.enabled);
                return {
                  content: [
                    {
                      type: 'text' as const,
                      text: `Pipelines ${params.enabled ? 'enabled' : 'disabled'} successfully`,
                    },
                  ],
                };
              }
    
              case 'list_variables': {
                const result = await pipelinesApi.listVariables(workspace, repo_slug, {
                  page: params.page,
                  pagelen: params.pagelen,
                });
                return {
                  content: [
                    {
                      type: 'text' as const,
                      text: formatOutput(
                        paginateResult(result),
                        format,
                        PIPELINE_VARIABLE_COMPACT_FIELDS
                      ),
                    },
                  ],
                };
              }
    
              case 'get_variable': {
                if (!params.variable_uuid) {
                  return {
                    content: [
                      {
                        type: 'text' as const,
                        text: 'Error: variable_uuid is required for get_variable action',
                      },
                    ],
                    isError: true,
                  };
                }
                const result = await pipelinesApi.getVariable(
                  workspace,
                  repo_slug,
                  params.variable_uuid
                );
                return {
                  content: [
                    {
                      type: 'text' as const,
                      text: formatOutput(result, format, PIPELINE_VARIABLE_COMPACT_FIELDS),
                    },
                  ],
                };
              }
    
              case 'create_variable': {
                if (!params.key || !params.value) {
                  return {
                    content: [
                      {
                        type: 'text' as const,
                        text: 'Error: key and value are required for create_variable action',
                      },
                    ],
                    isError: true,
                  };
                }
                const result = await pipelinesApi.createVariable(workspace, repo_slug, {
                  key: params.key,
                  value: params.value,
                  secured: params.secured,
                });
                return {
                  content: [
                    {
                      type: 'text' as const,
                      text: formatOutput(result, format, PIPELINE_VARIABLE_COMPACT_FIELDS),
                    },
                  ],
                };
              }
    
              case 'update_variable': {
                if (!params.variable_uuid) {
                  return {
                    content: [
                      {
                        type: 'text' as const,
                        text: 'Error: variable_uuid is required for update_variable action',
                      },
                    ],
                    isError: true,
                  };
                }
                const result = await pipelinesApi.updateVariable(
                  workspace,
                  repo_slug,
                  params.variable_uuid,
                  {
                    key: params.key,
                    value: params.value,
                    secured: params.secured,
                  }
                );
                return {
                  content: [
                    {
                      type: 'text' as const,
                      text: formatOutput(result, format, PIPELINE_VARIABLE_COMPACT_FIELDS),
                    },
                  ],
                };
              }
    
              case 'delete_variable': {
                if (!params.variable_uuid) {
                  return {
                    content: [
                      {
                        type: 'text' as const,
                        text: 'Error: variable_uuid is required for delete_variable action',
                      },
                    ],
                    isError: true,
                  };
                }
                await pipelinesApi.deleteVariable(workspace, repo_slug, params.variable_uuid);
                return {
                  content: [{ type: 'text' as const, text: 'Variable deleted successfully' }],
                };
              }
    
              default:
                return {
                  content: [{ type: 'text' as const, text: `Unknown action: ${action}` }],
                  isError: true,
                };
            }
          } catch (error) {
            const message = error instanceof Error ? error.message : 'Unknown error';
            return {
              content: [{ type: 'text' as const, text: `Error: ${message}` }],
              isError: true,
            };
          }
        }
      );
    }
  • Zod input schema for the bitbucket_pipelines tool, defining all parameters including action enum, workspace, repo_slug, pipeline_uuid, step_uuid, branch_name, pattern, variables, enabled, variable_uuid, key, value, secured, sort, target_branch, page, pagelen, and format
    {
      action: z
        .enum([
          'list',
          'get',
          'trigger',
          'trigger_custom',
          'stop',
          'list_steps',
          'get_step',
          'get_logs',
          'get_config',
          'set_enabled',
          'list_variables',
          'get_variable',
          'create_variable',
          'update_variable',
          'delete_variable',
        ])
        .describe('Action to perform'),
      workspace: z
        .string()
        .optional()
        .describe('Workspace slug (uses BITBUCKET_WORKSPACE env if omitted)'),
      repo_slug: z.string().describe('Repository slug'),
      // For get/stop/list_steps actions
      pipeline_uuid: z.string().optional().describe('Pipeline UUID'),
      // For get_step/get_logs actions
      step_uuid: z.string().optional().describe('Step UUID'),
      // For trigger actions
      branch_name: z
        .string()
        .optional()
        .describe('Branch name to trigger pipeline on (required for trigger/trigger_custom)'),
      pattern: z.string().optional().describe('Custom pipeline pattern (for trigger_custom)'),
      variables: z
        .array(
          z.object({
            key: z.string(),
            value: z.string(),
            secured: z.boolean().optional(),
          })
        )
        .optional()
        .describe('Pipeline variables for trigger'),
      // For set_enabled action
      enabled: z.boolean().optional().describe('Enable or disable pipelines'),
      // For variable actions
      variable_uuid: z.string().optional().describe('Variable UUID'),
      key: z.string().optional().describe('Variable key'),
      value: z.string().optional().describe('Variable value'),
      secured: z.boolean().optional().describe('Whether variable is secured'),
      // For list action
      sort: z.string().optional().describe('Sort field'),
      target_branch: z.string().optional().describe('Filter by target branch'),
      // Pagination
      page: z.number().optional().describe('Page number for pagination'),
      pagelen: z.number().optional().describe('Results per page (default: 25, max 100)'),
      // Output format
      format: z
        .enum(['json', 'toon', 'compact'])
        .optional()
        .describe(
          'Output format: json (full), toon (compact tokens), compact (essential fields only)'
        ),
    },
  • PipelinesAPI class with methods for all pipeline operations: list, get, trigger, triggerBranch, triggerCustom, stop, listSteps, getStep, getStepLogs, listVariables, getVariable, createVariable, updateVariable, deleteVariable, getConfig, setEnabled
    export class PipelinesAPI {
      constructor(private readonly client: BitbucketClient) {}
    
      /**
       * List pipelines for a repository
       */
      async list(
        workspace: string,
        repoSlug: string,
        options?: ListPipelinesOptions
      ): Promise<PaginatedResponse<Pipeline>> {
        const params: Record<string, string | number | boolean | undefined> = {
          ...buildPaginationParams(options),
          sort: options?.sort,
          'target.branch': options?.['target.branch'],
          'target.ref_name': options?.['target.ref_name'],
        };
        return this.client.getPaginated<Pipeline>(
          `/repositories/${workspace}/${repoSlug}/pipelines`,
          params
        );
      }
    
      /**
       * Get a specific pipeline
       */
      async get(workspace: string, repoSlug: string, pipelineUuid: string): Promise<Pipeline> {
        return this.client.get<Pipeline>(
          `/repositories/${workspace}/${repoSlug}/pipelines/${pipelineUuid}`
        );
      }
    
      /**
       * Trigger a new pipeline
       */
      async trigger(
        workspace: string,
        repoSlug: string,
        request: TriggerPipelineRequest
      ): Promise<Pipeline> {
        return this.client.post<Pipeline>(`/repositories/${workspace}/${repoSlug}/pipelines`, request);
      }
    
      /**
       * Trigger a pipeline for a branch
       */
      async triggerBranch(
        workspace: string,
        repoSlug: string,
        branchName: string,
        variables?: Array<{ key: string; value: string; secured?: boolean }>
      ): Promise<Pipeline> {
        return this.trigger(workspace, repoSlug, {
          target: {
            type: 'pipeline_ref_target',
            ref_type: 'branch',
            ref_name: branchName,
          },
          variables,
        });
      }
    
      /**
       * Trigger a custom pipeline
       */
      async triggerCustom(
        workspace: string,
        repoSlug: string,
        branchName: string,
        pattern: string,
        variables?: Array<{ key: string; value: string; secured?: boolean }>
      ): Promise<Pipeline> {
        return this.trigger(workspace, repoSlug, {
          target: {
            type: 'pipeline_ref_target',
            ref_type: 'branch',
            ref_name: branchName,
            selector: {
              type: 'custom',
              pattern,
            },
          },
          variables,
        });
      }
    
      /**
       * Stop a running pipeline
       */
      async stop(workspace: string, repoSlug: string, pipelineUuid: string): Promise<void> {
        await this.client.post(
          `/repositories/${workspace}/${repoSlug}/pipelines/${pipelineUuid}/stop_pipeline`
        );
      }
    
      /**
       * List pipeline steps
       */
      async listSteps(
        workspace: string,
        repoSlug: string,
        pipelineUuid: string,
        options?: PaginationOptions
      ): Promise<PaginatedResponse<PipelineStep>> {
        const params = buildPaginationParams(options);
        return this.client.getPaginated<PipelineStep>(
          `/repositories/${workspace}/${repoSlug}/pipelines/${pipelineUuid}/steps`,
          params
        );
      }
    
      /**
       * Get a specific pipeline step
       */
      async getStep(
        workspace: string,
        repoSlug: string,
        pipelineUuid: string,
        stepUuid: string
      ): Promise<PipelineStep> {
        return this.client.get<PipelineStep>(
          `/repositories/${workspace}/${repoSlug}/pipelines/${pipelineUuid}/steps/${stepUuid}`
        );
      }
    
      /**
       * Get pipeline step logs
       */
      async getStepLogs(
        workspace: string,
        repoSlug: string,
        pipelineUuid: string,
        stepUuid: string
      ): Promise<string> {
        return this.client.getRaw(
          `/repositories/${workspace}/${repoSlug}/pipelines/${pipelineUuid}/steps/${stepUuid}/log`
        );
      }
    
      /**
       * List repository pipeline variables
       */
      async listVariables(
        workspace: string,
        repoSlug: string,
        options?: PaginationOptions
      ): Promise<PaginatedResponse<PipelineVariable>> {
        const params = buildPaginationParams(options);
        return this.client.getPaginated<PipelineVariable>(
          `/repositories/${workspace}/${repoSlug}/pipelines_config/variables`,
          params
        );
      }
    
      /**
       * Get a specific pipeline variable
       */
      async getVariable(
        workspace: string,
        repoSlug: string,
        variableUuid: string
      ): Promise<PipelineVariable> {
        return this.client.get<PipelineVariable>(
          `/repositories/${workspace}/${repoSlug}/pipelines_config/variables/${variableUuid}`
        );
      }
    
      /**
       * Create a pipeline variable
       */
      async createVariable(
        workspace: string,
        repoSlug: string,
        variable: { key: string; value: string; secured?: boolean }
      ): Promise<PipelineVariable> {
        return this.client.post<PipelineVariable>(
          `/repositories/${workspace}/${repoSlug}/pipelines_config/variables`,
          variable
        );
      }
    
      /**
       * Update a pipeline variable
       */
      async updateVariable(
        workspace: string,
        repoSlug: string,
        variableUuid: string,
        variable: { key?: string; value?: string; secured?: boolean }
      ): Promise<PipelineVariable> {
        return this.client.put<PipelineVariable>(
          `/repositories/${workspace}/${repoSlug}/pipelines_config/variables/${variableUuid}`,
          variable
        );
      }
    
      /**
       * Delete a pipeline variable
       */
      async deleteVariable(workspace: string, repoSlug: string, variableUuid: string): Promise<void> {
        await this.client.delete(
          `/repositories/${workspace}/${repoSlug}/pipelines_config/variables/${variableUuid}`
        );
      }
    
      /**
       * Get pipeline configuration
       */
      async getConfig(workspace: string, repoSlug: string): Promise<{ enabled: boolean }> {
        return this.client.get<{ enabled: boolean }>(
          `/repositories/${workspace}/${repoSlug}/pipelines_config`
        );
      }
    
      /**
       * Enable or disable pipelines
       */
      async setEnabled(workspace: string, repoSlug: string, enabled: boolean): Promise<void> {
        await this.client.put(`/repositories/${workspace}/${repoSlug}/pipelines_config`, {
          enabled,
        });
      }
    }
  • Compact field definitions for pipeline (PIPELINE_COMPACT_FIELDS), pipeline step (PIPELINE_STEP_COMPACT_FIELDS), and pipeline variable (PIPELINE_VARIABLE_COMPACT_FIELDS) used for compact output format
    export const PIPELINE_COMPACT_FIELDS = [
      'uuid',
      'build_number',
      'state.name',
      'state.result.name',
      'target.ref_name',
      'target.ref_type',
      'creator.display_name',
      'created_on',
      'completed_on',
      'duration_in_seconds',
    ];
    
    /**
     * Pipeline Step - Essential fields for pipeline step listings
     */
    export const PIPELINE_STEP_COMPACT_FIELDS = [
      'uuid',
      'name',
      'state.name',
      'state.result.name',
      'started_on',
      'completed_on',
      'duration_in_seconds',
    ];
    
    /**
     * Pipeline Variable - Essential fields for variable listings
     */
    export const PIPELINE_VARIABLE_COMPACT_FIELDS = [
      'uuid',
      'key',
      'value',
      'secured',
    ];
Behavior3/5

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

With no annotations, the description must disclose behavioral traits. It lists actions and some constraints (e.g., branch_name required for trigger/trigger_custom), but lacks details on side effects, auth needs, rate limits, or idempotency for actions like trigger, stop, and set_enabled.

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

Conciseness4/5

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

The description is somewhat lengthy due to listing 15 actions, but each line is clear and front-loaded. It could be more concise by grouping similar actions, but overall it is well-structured and easy to parse.

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

Completeness3/5

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

Given the tool's complexity (18 parameters, many actions), the description covers the actions list but lacks explanation of return values (no output schema), error scenarios, or usage examples. It is adequate but not comprehensive.

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 coverage is 100%, so the baseline is 3. The description adds a brief summary of actions but does not elaborate on parameter meanings beyond what the schema already provides (e.g., variables structure, format options).

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

Purpose5/5

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

The description lists 15 specific sub-actions (list, get, trigger, etc.), each with a clear verb+resource pattern. It clearly distinguishes from sibling tools by focusing exclusively on Bitbucket Pipelines CI/CD management.

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

Usage Guidelines3/5

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

The description implicitly tells when to use this tool (for managing pipelines) but provides no explicit guidance on when to choose one action over another or when not to use this tool compared to alternatives.

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/icy-r/bitbucket-mcp'

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