Skip to main content
Glama

add_comment

Add comments to Bitbucket pull requests with options for general feedback, replies, inline code comments, and code suggestions. Supports line numbers, code snippets, and multi-line replacements for precise feedback.

Instructions

Add a comment to a pull request. Supports: 1) General PR comments, 2) Replies to existing comments, 3) Inline comments on specific code lines (using line_number OR code_snippet), 4) Code suggestions for single or multi-line replacements. For inline comments, you can either provide exact line_number or use code_snippet to auto-detect the line.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
code_snippetNoExact code text from the diff to find and comment on. Use this instead of line_number for auto-detection. Must match exactly including whitespace (optional)
comment_textYesThe main comment text. For suggestions, this is the explanation before the code suggestion.
file_pathNoFile path for inline comment. Required for inline comments. Example: "src/components/Button.js" (optional)
line_numberNoExact line number in the file. Use this OR code_snippet, not both. Required with file_path unless using code_snippet (optional)
line_typeNoType of line: ADDED (green/new lines), REMOVED (red/deleted lines), or CONTEXT (unchanged lines). Default: CONTEXT
match_strategyNoHow to handle multiple matches when using code_snippet. "strict": fail with detailed error showing all matches. "best": automatically pick the highest confidence match. Default: "strict"
parent_comment_idNoID of comment to reply to. Use this to create threaded conversations (optional)
pull_request_idYesPull request ID
repositoryYesRepository slug (e.g., "my-repo")
search_contextNoAdditional context lines to help locate the exact position when using code_snippet. Useful when the same code appears multiple times (optional)
suggestionNoReplacement code for a suggestion. Creates a suggestion block that can be applied in Bitbucket UI. Requires file_path and line_number. For multi-line, include newlines in the string (optional)
suggestion_end_lineNoFor multi-line suggestions: the last line number to replace. If not provided, only replaces the single line at line_number (optional)
workspaceYesBitbucket workspace/project key (e.g., "PROJ")

Implementation Reference

  • Main execution logic for the add_comment tool: argument validation, line resolution from code snippets, suggestion formatting, API request construction for Bitbucket Server/Cloud, and posting the comment with response formatting.
    async handleAddComment(args: any) { if (!isAddCommentArgs(args)) { throw new McpError( ErrorCode.InvalidParams, 'Invalid arguments for add_comment' ); } let { workspace, repository, pull_request_id, comment_text, parent_comment_id, file_path, line_number, line_type, suggestion, suggestion_end_line, code_snippet, search_context, match_strategy = 'strict' } = args; let sequentialPosition: number | undefined; if (code_snippet && !line_number && file_path) { try { const resolved = await this.resolveLineFromCode( workspace, repository, pull_request_id, file_path, code_snippet, search_context, match_strategy ); line_number = resolved.line_number; line_type = resolved.line_type; sequentialPosition = resolved.sequential_position; } catch (error) { throw error; } } if (suggestion && (!file_path || !line_number)) { throw new McpError( ErrorCode.InvalidParams, 'Suggestions require file_path and line_number to be specified' ); } const isInlineComment = file_path !== undefined && line_number !== undefined; let finalCommentText = comment_text; if (suggestion) { finalCommentText = formatSuggestionComment( comment_text, suggestion, line_number, suggestion_end_line || line_number ); } try { let apiPath: string; let requestBody: any; if (this.apiClient.getIsServer()) { // Bitbucket Server API apiPath = `/rest/api/1.0/projects/${workspace}/repos/${repository}/pull-requests/${pull_request_id}/comments`; requestBody = { text: finalCommentText }; if (parent_comment_id !== undefined) { requestBody.parent = { id: parent_comment_id }; } if (isInlineComment) { requestBody.anchor = { line: line_number, lineType: line_type || 'CONTEXT', fileType: line_type === 'REMOVED' ? 'FROM' : 'TO', path: file_path, diffType: 'EFFECTIVE' }; } } else { // Bitbucket Cloud API apiPath = `/repositories/${workspace}/${repository}/pullrequests/${pull_request_id}/comments`; requestBody = { content: { raw: finalCommentText } }; if (parent_comment_id !== undefined) { requestBody.parent = { id: parent_comment_id }; } if (isInlineComment) { requestBody.inline = { to: line_number, path: file_path }; } } const comment = await this.apiClient.makeRequest<any>('post', apiPath, requestBody); const responseMessage = suggestion ? 'Comment with code suggestion added successfully' : (isInlineComment ? 'Inline comment added successfully' : 'Comment added successfully'); return { content: [ { type: 'text', text: JSON.stringify({ message: responseMessage, comment: { id: comment.id, text: this.apiClient.getIsServer() ? comment.text : comment.content.raw, author: this.apiClient.getIsServer() ? comment.author.displayName : comment.user.display_name, created_on: this.apiClient.getIsServer() ? new Date(comment.createdDate).toLocaleString() : comment.created_on, file_path: isInlineComment ? file_path : undefined, line_number: isInlineComment ? line_number : undefined, line_type: isInlineComment ? (line_type || 'CONTEXT') : undefined, has_suggestion: !!suggestion, suggestion_lines: suggestion ? (suggestion_end_line ? `${line_number}-${suggestion_end_line}` : `${line_number}`) : undefined } }, null, 2), }, ], }; } catch (error) { return this.apiClient.handleApiError(error, `adding ${isInlineComment ? 'inline ' : ''}comment to pull request ${pull_request_id} in ${workspace}/${repository}`); } }
  • JSON Schema definition for the add_comment tool input parameters, including descriptions and validation rules for all fields like workspace, comment_text, file_path, line_number, suggestion, code_snippet, etc.
    name: 'add_comment', description: 'Add a comment to a pull request. Supports: 1) General PR comments, 2) Replies to existing comments, 3) Inline comments on specific code lines (using line_number OR code_snippet), 4) Code suggestions for single or multi-line replacements. For inline comments, you can either provide exact line_number or use code_snippet to auto-detect the line.', inputSchema: { type: 'object', properties: { workspace: { type: 'string', description: 'Bitbucket workspace/project key (e.g., "PROJ")', }, repository: { type: 'string', description: 'Repository slug (e.g., "my-repo")', }, pull_request_id: { type: 'number', description: 'Pull request ID', }, comment_text: { type: 'string', description: 'The main comment text. For suggestions, this is the explanation before the code suggestion.', }, parent_comment_id: { type: 'number', description: 'ID of comment to reply to. Use this to create threaded conversations (optional)', }, file_path: { type: 'string', description: 'File path for inline comment. Required for inline comments. Example: "src/components/Button.js" (optional)', }, line_number: { type: 'number', description: 'Exact line number in the file. Use this OR code_snippet, not both. Required with file_path unless using code_snippet (optional)', }, line_type: { type: 'string', description: 'Type of line: ADDED (green/new lines), REMOVED (red/deleted lines), or CONTEXT (unchanged lines). Default: CONTEXT', enum: ['ADDED', 'REMOVED', 'CONTEXT'], }, suggestion: { type: 'string', description: 'Replacement code for a suggestion. Creates a suggestion block that can be applied in Bitbucket UI. Requires file_path and line_number. For multi-line, include newlines in the string (optional)', }, suggestion_end_line: { type: 'number', description: 'For multi-line suggestions: the last line number to replace. If not provided, only replaces the single line at line_number (optional)', }, code_snippet: { type: 'string', description: 'Exact code text from the diff to find and comment on. Use this instead of line_number for auto-detection. Must match exactly including whitespace (optional)', }, search_context: { type: 'object', properties: { before: { type: 'array', items: { type: 'string' }, description: 'Array of code lines that appear BEFORE the target line. Helps disambiguate when code_snippet appears multiple times', }, after: { type: 'array', items: { type: 'string' }, description: 'Array of code lines that appear AFTER the target line. Helps disambiguate when code_snippet appears multiple times', }, }, description: 'Additional context lines to help locate the exact position when using code_snippet. Useful when the same code appears multiple times (optional)', }, match_strategy: { type: 'string', enum: ['strict', 'best'], description: 'How to handle multiple matches when using code_snippet. "strict": fail with detailed error showing all matches. "best": automatically pick the highest confidence match. Default: "strict"', }, }, required: ['workspace', 'repository', 'pull_request_id', 'comment_text'], }, },
  • src/index.ts:104-105 (registration)
    Tool registration and dispatch: routes 'add_comment' calls to the PullRequestHandlers.handleAddComment method.
    case 'add_comment': return this.pullRequestHandlers.handleAddComment(request.params.arguments);
  • Type guard function isAddCommentArgs used in the handler for runtime input validation matching the tool schema.
    export const isAddCommentArgs = ( args: any ): args is { workspace: string; repository: string; pull_request_id: number; comment_text: string; parent_comment_id?: number; file_path?: string; line_number?: number; line_type?: 'ADDED' | 'REMOVED' | 'CONTEXT'; suggestion?: string; suggestion_end_line?: number; code_snippet?: string; search_context?: { before?: string[]; after?: string[]; }; match_strategy?: 'strict' | 'best'; } => typeof args === 'object' && args !== null && typeof args.workspace === 'string' && typeof args.repository === 'string' && typeof args.pull_request_id === 'number' && typeof args.comment_text === 'string' && (args.parent_comment_id === undefined || typeof args.parent_comment_id === 'number') && (args.file_path === undefined || typeof args.file_path === 'string') && (args.line_number === undefined || typeof args.line_number === 'number') && (args.line_type === undefined || ['ADDED', 'REMOVED', 'CONTEXT'].includes(args.line_type)) && (args.suggestion === undefined || typeof args.suggestion === 'string') && (args.suggestion_end_line === undefined || typeof args.suggestion_end_line === 'number') && (args.code_snippet === undefined || typeof args.code_snippet === 'string') && (args.search_context === undefined || ( typeof args.search_context === 'object' && (args.search_context.before === undefined || Array.isArray(args.search_context.before)) && (args.search_context.after === undefined || Array.isArray(args.search_context.after)) )) && (args.match_strategy === undefined || ['strict', 'best'].includes(args.match_strategy));

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/pdogra1299/bitbucket-mcp-server'

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