# Create Merge Request — GitLab

> Open a new merge request from one branch into another. Use this for "open an MR", "raise a merge request", "submit my branch for review". Both branches must already exist in the project — use List Repo Branches to check, or Create Branch…

- Key: `gitlab-create-merge-request`
- Type: Action (Write)
- Version: 0.0.1
- App: GitLab (`gitlab`) — https://pipedream.com/apps/gitlab.md
- This page (HTML): https://pipedream.com/apps/gitlab/actions/create-merge-request
- Hints: open-world
- Source: https://github.com/PipedreamHQ/pipedream/blob/master/components/gitlab/actions/create-merge-request/create-merge-request.mjs

## Description

Open a new merge request from one branch into another. Use this for "open an MR", "raise a merge request", "submit my branch for review". Both branches must already exist in the project — use **List Repo Branches** to check, or **Create Branch** to make one. Reviewers and assignees are given as usernames and resolved to IDs automatically; a username that is not a member of the project is rejected rather than silently dropped. Set **Draft** to `true` for work that is not ready for review — GitLab expresses this by prefixing the title with `Draft:`, which this action does for you and which blocks merging until removed. After creating, use **Get Merge Request** to check its pipeline and merge readiness. [See the documentation](https://docs.gitlab.com/api/merge_requests/#create-mr)

## Props

| Prop | Type | Required | Description |
|---|---|---|---|
| `projectId` | `string` | Yes | The project, given either as its path — group/project or group/subgroup/project, e.g. backend/payments — or as its numeric project ID. The path is what appears in the project URL and is usually what a user will name, so prefer it. A pasted GitLab URL also works. Use List Projects to find the path if you only know part of the name. |
| `sourceBranch` | `string` | Yes | The branch holding the changes, e.g. feat/retry-cap. Must already exist in the project — use List Repo Branches to check. |
| `targetBranch` | `string` | Yes | The branch to merge into, e.g. main or master. Use List Repo Branches to confirm the project's default branch rather than assuming main. |
| `title` | `string` | Yes | The merge request title. Do not prefix it with Draft: by hand — set Draft instead. |
| `description` | `string` | No | The merge request description, in GitLab-flavored Markdown. Mentioning Closes #123 links and closes that issue on merge. |
| `draft` | `boolean` | No | Whether to open the merge request as a draft, which blocks merging until the draft flag is removed. Defaults to false. |
| `reviewerUsernames` | `string[]` | No | Usernames to request review from, e.g. ["jdoe"]. Resolved to user IDs automatically; each must be a member of the project. |
| `assigneeUsernames` | `string[]` | No | Usernames to assign the merge request to. Resolved to user IDs automatically; each must be a member of the project. |
| `labels` | `string[]` | No | Labels to apply to the merge request, by name. Each must already exist in the project — GitLab creates a label it does not recognize rather than rejecting it, so a mis-cased or invented name silently adds a new project label. Use List Project Labels to get the exact names. |
| `removeSourceBranch` | `boolean` | No | Whether to delete the source branch when the merge request is merged. Defaults to the project's own setting when left blank. |
| `squash` | `boolean` | No | Whether to squash the commits into one when merging. |

## Run it

**MCP**

```ts
import { Client } from "@modelcontextprotocol/sdk/client/index.js"
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"
import { PipedreamClient } from "@pipedream/sdk"

const pd = new PipedreamClient({
  projectId: process.env.PIPEDREAM_PROJECT_ID!,
  clientId: process.env.PIPEDREAM_CLIENT_ID!,
  clientSecret: process.env.PIPEDREAM_CLIENT_SECRET!,
  projectEnvironment: "production",
})

const accessToken = await pd.rawAccessToken

const transport = new StreamableHTTPClientTransport(
  new URL("https://remote.mcp.pipedream.net/v3"),
  {
    requestInit: {
      headers: {
        Authorization: `Bearer ${accessToken}`,
        "x-pd-project-id": process.env.PIPEDREAM_PROJECT_ID!,
        "x-pd-environment": "production",
        "x-pd-external-user-id": "{external_user_id}", // any stable ID for this user in your system
        "x-pd-app-slug": "gitlab",
      },
    },
  },
)

const mcp = new Client({ name: "my-agent", version: "1.0.0" })
await mcp.connect(transport)

const { tools } = await mcp.listTools()

// listTools() hands your model this tool's input schema, so it can
// fill the arguments itself:
const result = await mcp.callTool({
  name: "gitlab-create-merge-request",
  arguments: {
    projectId: "Project",
    sourceBranch: "Source Branch",
  },
})
```

**TypeScript**

```ts
import { PipedreamClient } from "@pipedream/sdk"

const pd = new PipedreamClient({
  projectId: process.env.PIPEDREAM_PROJECT_ID!,
  clientId: process.env.PIPEDREAM_CLIENT_ID!,
  clientSecret: process.env.PIPEDREAM_CLIENT_SECRET!,
  projectEnvironment: "production",
})

const result = await pd.actions.run({
  id: "gitlab-create-merge-request",
  externalUserId: "{external_user_id}", // any stable ID for this user in your system
  configuredProps: {
    gitlab: { authProvisionId: "apn_xxxxxxx" },
    projectId: "Project",
    sourceBranch: "Source Branch",
  },
})

console.log(result)
```

**cURL**

```bash
curl -X POST https://api.pipedream.com/v1/connect/{project_id}/actions/run \
  -H "Content-Type: application/json" \
  -H "X-PD-Environment: production" \
  -H "Authorization: Bearer {access_token}" \
  -d '{
    "external_user_id": "{external_user_id}",
    "id": "gitlab-create-merge-request",
    "configured_props": {
      "gitlab": { "authProvisionId": "apn_xxxxxxx" },
      "projectId": "Project",
      "sourceBranch": "Source Branch"
    }
  }'
```

---

- App: https://pipedream.com/apps/gitlab.md · All apps: https://pipedream.com/apps
