@daghis/teamcity-mcp 2.10.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.11.0](https://github.com/Daghis/teamcity-mcp/compare/teamcity-mcp-v2.10.0...teamcity-mcp-v2.11.0) (2026-05-03)
4
+
5
+
6
+ ### Features
7
+
8
+ * **artifacts:** add list_build_artifacts tool for subdirectory browsing ([#489](https://github.com/Daghis/teamcity-mcp/issues/489)) ([eacad61](https://github.com/Daghis/teamcity-mcp/commit/eacad6115cbb33a6e660bd096e59869c4fcf4ea8))
9
+
3
10
  ## [2.10.0](https://github.com/Daghis/teamcity-mcp/compare/teamcity-mcp-v2.9.0...teamcity-mcp-v2.10.0) (2026-04-26)
4
11
 
5
12
 
package/dist/index.js CHANGED
@@ -1205,7 +1205,7 @@ function debug2(message, meta) {
1205
1205
  // package.json
1206
1206
  var package_default = {
1207
1207
  name: "@daghis/teamcity-mcp",
1208
- version: "2.10.0",
1208
+ version: "2.11.0",
1209
1209
  description: "Model Control Protocol server for TeamCity CI/CD integration with AI coding assistants",
1210
1210
  mcpName: "io.github.Daghis/teamcity",
1211
1211
  main: "dist/index.js",
@@ -1294,7 +1294,7 @@ var package_default = {
1294
1294
  "eslint-plugin-prettier": "^5.0.1",
1295
1295
  globals: "^17.4.0",
1296
1296
  jest: "^30.1.3",
1297
- "jest-junit": "^16.0.0",
1297
+ "jest-junit": "^17.0.0",
1298
1298
  "js-yaml": "^4.1.1",
1299
1299
  prettier: "^3.1.0",
1300
1300
  "ts-jest": "^29.4.9",
@@ -1550,13 +1550,20 @@ var ArtifactManager = class _ArtifactManager {
1550
1550
  const buildLocator = toBuildLocator(buildId);
1551
1551
  const response = await this.client.modules.builds.getFilesListOfBuild(
1552
1552
  buildLocator,
1553
- void 0,
1553
+ options.path,
1554
1554
  void 0,
1555
1555
  "file(name,fullName,size,modificationTime,href,children(file(name,fullName,size,modificationTime,href)))"
1556
1556
  );
1557
1557
  const baseUrl = this.getBaseUrl();
1558
1558
  const artifactPayload = this.ensureArtifactListingResponse(response.data, buildId);
1559
- let artifacts = this.parseArtifacts(artifactPayload, buildId, options.includeNested, baseUrl);
1559
+ let artifacts = this.parseArtifacts(
1560
+ artifactPayload,
1561
+ buildId,
1562
+ options.includeNested,
1563
+ baseUrl,
1564
+ [],
1565
+ options.includeDirectories
1566
+ );
1560
1567
  artifacts = this.applyFilters(artifacts, options);
1561
1568
  if (options.limit ?? options.offset) {
1562
1569
  artifacts = this.paginate(
@@ -1788,7 +1795,7 @@ var ArtifactManager = class _ArtifactManager {
1788
1795
  }
1789
1796
  return payload;
1790
1797
  }
1791
- parseArtifacts(data, buildId, includeNested, baseUrl, parentSegments = []) {
1798
+ parseArtifacts(data, buildId, includeNested, baseUrl, parentSegments = [], includeDirectories) {
1792
1799
  const artifacts = [];
1793
1800
  const files = data.file ?? [];
1794
1801
  for (const file of files) {
@@ -1796,13 +1803,24 @@ var ArtifactManager = class _ArtifactManager {
1796
1803
  const resolvedPath = pathSegments.join("/");
1797
1804
  const isDirectory = Boolean(file.children);
1798
1805
  if (isDirectory) {
1806
+ if (includeDirectories && resolvedPath) {
1807
+ artifacts.push({
1808
+ name: file.name ?? pathSegments[pathSegments.length - 1] ?? "",
1809
+ path: resolvedPath,
1810
+ size: file.size ?? 0,
1811
+ modificationTime: file.modificationTime ?? "",
1812
+ downloadUrl: `${baseUrl}/app/rest/builds/id:${buildId}/artifacts/content/${this.encodeArtifactPath(pathSegments)}`,
1813
+ isDirectory: true
1814
+ });
1815
+ }
1799
1816
  if (includeNested && file.children) {
1800
1817
  const nested = this.parseArtifacts(
1801
1818
  file.children,
1802
1819
  buildId,
1803
1820
  includeNested,
1804
1821
  baseUrl,
1805
- pathSegments
1822
+ pathSegments,
1823
+ includeDirectories
1806
1824
  );
1807
1825
  artifacts.push(...nested);
1808
1826
  }
@@ -41424,6 +41442,72 @@ var DEV_TOOLS = [
41424
41442
  );
41425
41443
  }
41426
41444
  },
41445
+ {
41446
+ name: "list_build_artifacts",
41447
+ annotations: {
41448
+ readOnlyHint: true,
41449
+ destructiveHint: false,
41450
+ idempotentHint: true,
41451
+ openWorldHint: true
41452
+ },
41453
+ description: "List artifact files and directories for a build, optionally browsing into subdirectories. Returns an array of artifact entries with name, path, size, and isDirectory flag.",
41454
+ inputSchema: {
41455
+ type: "object",
41456
+ properties: {
41457
+ ...buildIdentifierInputProperties,
41458
+ path: {
41459
+ type: "string",
41460
+ description: 'Sub-path to list (e.g. "okd" or "okd/subdir"). Omit to list top-level artifacts.'
41461
+ },
41462
+ includeNested: {
41463
+ type: "boolean",
41464
+ description: "Recursively include all files within subdirectories (default: false)"
41465
+ },
41466
+ nameFilter: {
41467
+ type: "string",
41468
+ description: 'Glob pattern to filter artifacts by name (e.g. "*.yaml")'
41469
+ },
41470
+ pathFilter: {
41471
+ type: "string",
41472
+ description: "Glob pattern to filter artifacts by full path"
41473
+ },
41474
+ extension: {
41475
+ type: "string",
41476
+ description: 'Filter by file extension (e.g. "yaml", ".yaml")'
41477
+ }
41478
+ }
41479
+ },
41480
+ handler: async (args) => {
41481
+ const schema = buildIdentifierSchema.and(
41482
+ import_zod4.z.object({
41483
+ path: import_zod4.z.string().trim().min(1).optional(),
41484
+ includeNested: import_zod4.z.boolean().optional(),
41485
+ nameFilter: import_zod4.z.string().trim().min(1).optional(),
41486
+ pathFilter: import_zod4.z.string().trim().min(1).optional(),
41487
+ extension: import_zod4.z.string().trim().min(1).optional()
41488
+ })
41489
+ );
41490
+ return runTool(
41491
+ "list_build_artifacts",
41492
+ schema,
41493
+ async (typed) => {
41494
+ const adapter = createAdapterFromTeamCityAPI(TeamCityAPI.getInstance());
41495
+ const { locator: buildLocator } = resolveBuildLocator(typed);
41496
+ const manager = new ArtifactManager(adapter);
41497
+ const artifacts = await manager.listArtifacts(buildLocator, {
41498
+ path: typed.path,
41499
+ includeNested: typed.includeNested,
41500
+ includeDirectories: true,
41501
+ nameFilter: typed.nameFilter,
41502
+ pathFilter: typed.pathFilter,
41503
+ extension: typed.extension
41504
+ });
41505
+ return json({ artifacts });
41506
+ },
41507
+ args
41508
+ );
41509
+ }
41510
+ },
41427
41511
  {
41428
41512
  name: "download_build_artifact",
41429
41513
  annotations: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@daghis/teamcity-mcp",
3
- "version": "2.10.0",
3
+ "version": "2.11.0",
4
4
  "description": "Model Control Protocol server for TeamCity CI/CD integration with AI coding assistants",
5
5
  "mcpName": "io.github.Daghis/teamcity",
6
6
  "main": "dist/index.js",
@@ -89,7 +89,7 @@
89
89
  "eslint-plugin-prettier": "^5.0.1",
90
90
  "globals": "^17.4.0",
91
91
  "jest": "^30.1.3",
92
- "jest-junit": "^16.0.0",
92
+ "jest-junit": "^17.0.0",
93
93
  "js-yaml": "^4.1.1",
94
94
  "prettier": "^3.1.0",
95
95
  "ts-jest": "^29.4.9",
package/server.json CHANGED
@@ -7,13 +7,13 @@
7
7
  "source": "github"
8
8
  },
9
9
  "websiteUrl": "https://github.com/Daghis/teamcity-mcp",
10
- "version": "2.10.0",
10
+ "version": "2.11.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "registryBaseUrl": "https://registry.npmjs.org",
15
15
  "identifier": "@daghis/teamcity-mcp",
16
- "version": "2.10.0",
16
+ "version": "2.11.0",
17
17
  "runtimeHint": "npx",
18
18
  "runtimeArguments": [
19
19
  {