# Package a Custom Flow Connector as a 2GP Managed Package

Use custom flow connectors with MuleSoft Connector Builder to extend flows to any external service. Learn how to package a connector as a managed 2GP that you can list on AgentExchange or distribute privately.

Before you begin, create a custom flow connector using MuleSoft Connector Builder, and then export the connector as a JAR file (.jar). See [Creating Connectors](https://docs.mulesoft.com/connector-builder/creating-connectors) and [Packaging Connectors](https://docs.mulesoft.com/connector-builder/packaging-connectors) in *Mulesoft Documentation*.

Follow these steps to package a custom flow connector as a managed 2GP. Include only one connector per managed package, without any other app content.

## Create a Salesforce DX Project

In your local development environment, create a new Salesforce DX project by running the `sf project generate` Salesforce CLI command.

```nolang
sf project generate --name my-connector-project
cd my-connector-project
```

## Add Connector Metadata

Create the required directory structure and files for your custom flow connector.

In `force-app/main/default`, create the `integArtifactDefs` directory. Then, in `integArtifactDefs`, create these folders and files.

- **A folder for the connector**: The folder’s name must match the developerName of the connector’s JAR file (.jar) file. To find the developerName, open the JAR file that you exported from Mulesoft Connector Builder, locate the `flow-connector.ic` file within it, and then search for `developerName`. For example, if `flow-connector.ic` defines developerName as `MyConnector`, name your folder `MyConnector`.

  :::note
  Salesforce uses the folder name as the connector’s developer name in the org only when the name matches the JAR file’s internal definition.
  :::

- **The metadata file**: In the folder for the connector, create the metadata file and add the folder name to its file name. For example, if the folder for the connector is named `MyConnector`, then name the metadata file `MyConnector-meta.xml`.

- **A subfolder for the JAR file**: In the folder for the connector, create a subfolder for the JAR file. The name of this subfolder must be a version number, and it must match the version defined in the connector’s JAR file. To find the version number, open the JAR file, locate the `flow-connector.ic` file within it, and then search for `version`. For example, if `flow-connector.ic` defines version as `1.0.0`, name the subfolder `1.0.0`. Add the JAR file to this subfolder.

The resulting directory structure looks like this:

```nolang
force-app/main/default/integArtifactDefs/
└── MyConnector/
    ├── MyConnector-meta.xml
    └── 1.0.0/
        └── my-connector.jar
```

Then, in the metadata file (`MyConnector-meta.xml`), structure the metadata like this:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<IntegArtifactDef xmlns="http://soap.sforce.com/2006/04/metadata">
    <description>Connects Salesforce Flow to MySystem</description>
    <displayName>My Connector</displayName>
    <groupId>com.example.myconnector</groupId>
    <iconName>MyConnectorIcon</iconName>
    <isGlobal>true</isGlobal>
</IntegArtifactDef>
```

:::note
Don’t add a \<developerName> element to the metadata. Salesforce derives the connector’s developer name from the folder name under `integArtifactDefs`.
:::

This table describes each field in the metadata file.

| Field       | Required          | Description                                                                                                                                                                                                                  |
| ----------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| displayName | Yes               | The name of the connector that customers see in Flow Builder and Setup.                                                                                                                                                      |
| description | Yes               | A short description of what the connector does.                                                                                                                                                                              |
| groupId     | Yes               | A unique group identifier in reverse-DNS format (for example, `com.example.myconnector`). Must match the groupId value defined in your connector’s JAR (`flow-connector.ic`).                                                |
| isGlobal    | Yes for packaging | Must be `true` for the connector to be packaged in a 2GP managed package and made available in subscriber orgs that install your package. Package-private connectors aren’t supported yet. See the following important note. |
| iconName    | No                | The name of a static resource (SVG) used as the connector’s icon. See the Add an Icon section.                                                                                                                               |

:::important
Setting isGlobal to `true` makes the connector globally available in every subscriber org that installs your package. Any flow, Apex class, or component in that org can reference and invoke the connector. Customers may build flows that depend on the connector’s exact surface—its operations, parameters, and response shapes. Changes you make in future package versions may render those flows inoperable. Salesforce blocks subscriber upgrades when we detect backward-incompatible changes on minor or patch versions. Even so, review every change against the customer’s perspective before shipping. The platform can’t catch every semantic change.
:::

## Add an Icon (Optional)

Give your connector a custom icon that appears in Flow Builder and Setup.

1. Create an SVG icon.

   48×48 px is the size used for standard connectors.

2. Add the icon as a static resource.

   In `force-app/main/default/staticresources/`, create these two files with matching names.

   - `&lt;IconName&gt;.svg` — the SVG file.
   - `&lt;IconName&gt;.resource-meta.xml` — the metadata file. Set contentType to `image/svg+xml`.

3. Set iconName in your connector metadata file (`MyConnector-meta.xml`) to the static resource name (without the .svg extension).

   The match is case-sensitive.

   :::note
   The static resource must exist in the org before the `IntegArtifactDef` is deployed. Otherwise, the iconName reference doesn't resolve.
   :::

## Define the Managed Package

Update the project configuration file and create the package definition in your Dev Hub.

Add a new package entry to the project configuration file (`sfdx-project.json`). In this example, replace the placeholder values with the values for your managed package.

```json
{
  "packageAliases": {
    "MyConnectorPackage": "0Hoxx0000004ABCDE"
  },
  "packageDirectories": [
    {
      "path": "force-app",
      "package": "MyConnectorPackage",
      "versionName": "ver 0.1",
      "versionNumber": "0.1.0.NEXT",
      "default": true
    }
  ]
}
```

Then, create the package definition in your Dev Hub by running the `sf package create` CLI command.

```nolang
sf package create \
    --name "MyConnectorPackage" \
    --package-type Managed \
    --path force-app
```

## Create a Package Version

Before you create a package version, add the ExternalConnectivity feature to the scratch org definition file (`config/project-scratch-def.json`).

```json
{
  "features": ["ExternalConnectivity"]
}
```

For other scratch org configuration options, see [Scratch Org Features](https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_scratch_orgs_def_file_config_values.htm) in the *Salesforce DX Developer Guide*.

Then, create a package version by running the `sf package version create` CLI command.

:::note
Replace \<your-installation-key> with a password that you share with subscribers via your AgentExchange listing. The password gates package installs.
:::

```nolang
sf package version create \
    --package "MyConnectorPackage" \
    --installation-key <your-installation-key> \
    --code-coverage \
    --definition-file config/project-scratch-def.json \
    --wait 60
```

When the command finishes, it returns a package version ID (starting with 04t). Use this ID to install the managed package in test orgs and to associate it with your AgentExchange listing.

When you’re ready to move forward with listing your managed package on AgentExchange, make sure to verify the package’s listing readiness first. See [Check If Your Package Version Is Ready to List on AgentExchange](https://developer.salesforce.com/docs/atlas.en-us.packagingGuide.meta/packagingGuide/security_review_check_listing_readiness.htm) in the *ISVforce Guide*.
