Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,20 @@ Learn more and get started here:
- Other optional parameters for specific repository configurations
- Returns: Created repository details

5. `list_repositories`
6. `create_federated_repository`
- Create a new federated repository in Artifactory that replicates artifacts between multiple other federated repositories
- Inputs:
- `key` (string): Repository key
- `rclass` (string): Repository class (must be "federated")
- `packageType` (string): Package type of the repository
- `members` (optional array): List of federated members with URL, credentials, and configuration
- `description` (optional string): Repository description
- `projectKey` (optional string): Project key to assign the repository to
- `environments` (optional string[]): Environments to assign the repository to
- Other optional parameters for specific repository configurations
- Returns: Created repository details

7. `list_repositories`
- List all repositories in Artifactory with optional filtering
- Inputs:
- `type` (optional string): Filter repositories by type (local, remote, virtual, federated, distribution)
Expand Down Expand Up @@ -533,10 +546,9 @@ For Claude Desktop with SSE transport:
}
}
```
```
</details>


## License

This MCP server is licensed under the Apache License 2.0. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the Apache License 2.0. For more details, please see the LICENSE.md file in the project repository.
This MCP server is licensed under the Apache License 2.0. This means you are free to use, modify, and distribute the software, subject to the terms and conditions of the Apache License 2.0. For more details, please see the LICENSE.md file in the project repository.
48 changes: 47 additions & 1 deletion schemas/repositories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ export const PackageTypeEnum = z.enum([
"bower", "cargo", "chef", "cocoapods", "composer", "conan", "cran",
"debian", "docker", "Npm", "gems", "gitlfs", "go", "gradle", "helm", "ivy",
"maven", "nuget", "opkg", "p2", "pub", "puppet", "pypi", "rpm", "sbt",
"swift", "terraform", "vagrant", "yum", "generic"
"swift", "terraform", "vagrant", "yum", "generic", "alpine", "conda", "helmoci",
"huggingfaceml", "ansible", "oci"
]).describe("Package type of the repository");

export const BaseRepositorySchema = z.object({
Expand Down Expand Up @@ -206,6 +207,51 @@ export const CreateVirtualRepoSchema = BaseRepositorySchema.extend({
primaryKeyPairRef: z.string().optional().describe("Primary GPG key pair reference"),
secondaryKeyPairRef: z.string().optional().describe("Secondary GPG key pair reference")
});

export const CreateFederatedRepoSchema = BaseRepositorySchema.extend({
rclass: z.literal("federated").describe("The repository type"),
members: z.array(z.object({
url: z.string().describe("Full URL to ending with the repositoryName. Typically follows pattern: {baseUrl}/artifactory/{repoKey} where repoKey matches the primary repository key"),
enabled: z.boolean().default(true).describe("Represents the active state of the federated member.")
})).optional().describe("List of federated members. Members typically have the same repository key as the primary repository but on different Artifactory instances. URL format: {baseUrl}/artifactory/{repoKey} where repoKey should match the primary repository key for consistency"),
description: z.string().optional().describe("The federated repository public description"),
proxy: z.string().optional().describe("Proxy key"),
disableProxy: z.boolean().default(false),
notes: z.string().optional().describe("Some internal notes"),
includesPattern: z.string().default("**/*").describe("Pattern to define artifacts to include"),
excludesPattern: z.string().default("").describe("Pattern to define artifacts to exclude"),
repoLayoutRef: z.string().default("maven-2-default").describe("Repository layout reference"),
debianTrivialLayout: z.boolean().default(false).describe("Whether to use trivial layout for Debian repositories"),
checksumPolicyType: z.enum([
"client-checksums",
"server-generated-checksums"
]).default("client-checksums"),
handleReleases: z.boolean().default(true),
handleSnapshots: z.boolean().default(true),
maxUniqueSnapshots: z.number().default(0),
maxUniqueTags: z.number().default(0),
snapshotVersionBehavior: z.enum([
"unique",
"non-unique",
"deployer"
]).default("unique"),
suppressPomConsistencyChecks: z.boolean().default(false),
blackedOut: z.boolean().default(false),
xrayIndex: z.boolean().default(false),
propertySets: z.array(z.string()).optional(),
archiveBrowsingEnabled: z.boolean().default(false),
calculateYumMetadata: z.boolean().default(false),
yumRootDepth: z.number().default(0),
dockerApiVersion: z.string().default("V2"),
enableFileListsIndexing: z.boolean().default(false),
optionalIndexCompressionFormats: z.array(z.enum(["bz2", "lzma", "xz"])).optional(),
downloadRedirect: z.boolean().default(false),
cdnRedirect: z.boolean().default(false).describe("Applies to Artifactory Cloud Only"),
blockPushingSchema1: z.boolean().default(false),
primaryKeyPairRef: z.string().optional().describe("Primary GPG key pair reference"),
secondaryKeyPairRef: z.string().optional().describe("Secondary GPG key pair reference"),
priorityResolution: z.boolean().default(false).describe("Applies to all repository types excluding CocoaPods, Git LFS, NuGet V2, Opkg, RPM, Rust, Vagrant and VCS repositories")
});

export const JFrogPlatformReadinessSchema= z.object({
code: z.string()
Expand Down
22 changes: 22 additions & 0 deletions tools/repositories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
CreateLocalRepoSchema,
CreateRemoteRepoSchema,
CreateVirtualRepoSchema,
CreateFederatedRepoSchema,
ListRepositoriesParamsSchema,
JFrogRepositoryCreateResponseSchema,
JFrogPlatformReadinessSchema,
Expand Down Expand Up @@ -95,6 +96,15 @@ export async function createVirtualRepository(options: z.infer<typeof CreateVirt
return JFrogRepositoryCreateResponseSchema.parse(response);
}

export async function createFederatedRepository(options: z.infer<typeof CreateFederatedRepoSchema>) {
const response = await jfrogRequest(`/artifactory/api/repositories/${options.key}`, {
method: "PUT",
body: options
});

return JFrogRepositoryCreateResponseSchema.parse(response);
}

/* End of Api Calls Section */


Expand Down Expand Up @@ -154,6 +164,17 @@ const createVirtualRepositoryTool = {
}
};

const createFederatedRepositoryTool = {
name: "jfrog_create_federated_repository",
description: "Create a new federated repository in Artifactory that replicates artifacts between multiple other federated repositories. Note: Federated members typically use the same repository key as the primary repository but on different Artifactory instances. When specifying members, use URL format: {baseUrl}/artifactory/{repoKey} where repoKey should match the primary repository key for consistency",
inputSchema: zodToJsonSchema(CreateFederatedRepoSchema),
//outputSchema: zodToJsonSchema(JFrogRepositoryCreateResponseSchema),
handler: async (args: any) => {
const parsedArgs = CreateFederatedRepoSchema.parse(args);
return await createFederatedRepository(parsedArgs);
}
};

const listRepositoriesTool = {
name: "jfrog_list_repositories",
description: "List all repositories in Artifactory with optional filtering by type, package type, and project",
Expand All @@ -170,6 +191,7 @@ export const RepositoryTools =[
createLocalRepositoryTool,
createRemoteRepositoryTool,
createVirtualRepositoryTool,
createFederatedRepositoryTool,
setFolderPropertyTool,
listRepositoriesTool
];
Expand Down