Skip to main content
Glama
ttpears

GitLab MCP Server

by ttpears

create_note

Add comments or notes to GitLab issues and merge requests using Markdown formatting, with options for internal visibility and authentication.

Instructions

Add a comment/note to an issue or merge request (requires user authentication)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
projectPathYesFull path of the project (e.g., "group/project-name")
noteableTypeYesType of item to add a note to
iidYesIssue or merge request IID
bodyYesNote body (supports Markdown)
internalNoWhether the note is internal/confidential (only visible to project members)
userCredentialsNoYour GitLab credentials (optional - uses shared token if not provided)

Implementation Reference

  • Tool definition and handler for 'create_note'. Defines input schema (projectPath, noteableType, iid, body, internal), validates user credentials, and calls the GitLab client's createNote method.
    const createNoteTool: Tool = {
      name: 'create_note',
      title: 'Create Note',
      description: 'Add a comment/note to an issue or merge request (requires user authentication)',
      requiresAuth: true,
      requiresWrite: true,
      annotations: {
        readOnlyHint: false,
        destructiveHint: false,
        idempotentHint: false,
      },
      inputSchema: withUserAuth(z.object({
        projectPath: z.string().describe('Full path of the project (e.g., "group/project-name")'),
        noteableType: z.enum(['issue', 'merge_request']).describe('Type of item to add a note to'),
        iid: z.string().describe('Issue or merge request IID'),
        body: z.string().min(1).describe('Note body (supports Markdown)'),
        internal: z.boolean().default(false).describe('Whether the note is internal/confidential (only visible to project members)'),
      })),
      handler: async (input, client, userConfig) => {
        const credentials = input.userCredentials ? validateUserConfig(input.userCredentials) : userConfig;
        if (!credentials) {
          throw new Error('User authentication is required for creating notes. Please provide your GitLab credentials.');
        }
        const result = await client.createNote(input.projectPath, input.noteableType, input.iid, input.body, input.internal, credentials);
        if (result.errors && result.errors.length > 0) {
          throw new Error(`Failed to create note: ${result.errors.join(', ')}`);
        }
        return result.note;
      },
    };
  • Core implementation of createNote in GitLabGraphQLClient. Introspects schema, resolves noteable IID to global ID, constructs GraphQL mutation, and executes it to create a note on issues or merge requests.
    async createNote(
      projectPath: string,
      noteableType: 'issue' | 'merge_request',
      iid: string,
      body: string,
      internal: boolean = false,
      userConfig?: UserConfig
    ): Promise<any> {
      await this.introspectSchema(userConfig);
      const mutationType = this.schema?.getMutationType();
      const fields = mutationType ? mutationType.getFields() : {};
    
      const fieldName = fields['createNote'] ? 'createNote' : null;
      if (!fieldName) {
        throw new Error('createNote mutation is not available on this GitLab instance');
      }
    
      // Resolve the noteable IID to a global ID
      const noteableId = noteableType === 'issue'
        ? await this.getIssueId(projectPath, iid, userConfig)
        : await this.getMergeRequestId(projectPath, iid, userConfig);
    
      const mutation = gql`
        mutation createNote($input: CreateNoteInput!) {
          createNote(input: $input) {
            note {
              id
              body
              author { username name }
              createdAt
              url
              internal
            }
            errors
          }
        }
      `;
    
      const input: any = {
        noteableId,
        body,
      };
      if (internal) {
        input.internal = true;
      }
    
      const result = await this.query(mutation, { input }, userConfig, true);
      return result.createNote;
    }
  • Input schema definition for create_note tool using Zod validation with user credentials wrapper
    inputSchema: withUserAuth(z.object({
      projectPath: z.string().describe('Full path of the project (e.g., "group/project-name")'),
      noteableType: z.enum(['issue', 'merge_request']).describe('Type of item to add a note to'),
      iid: z.string().describe('Issue or merge request IID'),
      body: z.string().min(1).describe('Note body (supports Markdown)'),
      internal: z.boolean().default(false).describe('Whether the note is internal/confidential (only visible to project members)'),
    })),
  • src/tools.ts:1317-1349 (registration)
    Tool registration in module exports. createNoteTool is exported in writeTools array and included in the main tools export for MCP server registration
    export const writeTools: Tool[] = [
      createIssueTool,
      createMergeRequestTool,
      createNoteTool,
      managePipelineTool,
    ];
    
    export const searchTools: Tool[] = [
      globalSearchTool,
      searchProjectsTool,
      searchIssuesTool,
      searchMergeRequestsTool,
      getUserIssuesTool,
      getUserMergeRequestsTool,
      searchUsersTool,
      searchGroupsTool,
      searchLabelsTool,
      browseRepositoryTool,
      getFileContentTool,
      listGroupMembersTool,
    ];
    
    export const tools: Tool[] = [
      ...readOnlyTools,
      ...userAuthTools,
      ...writeTools,
      updateIssueTool,
      updateMergeRequestTool,
      resolvePathTool,
      getGroupProjectsTool,
      getTypeFieldsTool,
      ...searchTools,
    ];
  • src/index.ts:83-96 (registration)
    MCP server tool registration handler. The setupToolHandlers method registers all tools including create_note with the MCP server for listing and execution
    private setupToolHandlers(server: Server): void {
      server.setRequestHandler(ListToolsRequestSchema, async () => {
        return {
          tools: tools.map(tool => ({
            name: tool.name,
            ...(tool.title && { title: tool.title }),
            description: tool.description,
            inputSchema: toJsonSchema(tool.inputSchema),
            ...(tool.outputSchema && { outputSchema: toJsonSchema(tool.outputSchema) }),
            ...(tool.annotations && { annotations: tool.annotations }),
            ...(tool.icon && { icon: tool.icon }),
          })),
        };
      });

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/ttpears/gitlab-mcp'

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