@utaba/ucm-mcp-server 1.0.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.
Files changed (80) hide show
  1. package/LICENSE +29 -0
  2. package/README.md +79 -0
  3. package/dist/clients/UcmApiClient.d.ts +53 -0
  4. package/dist/clients/UcmApiClient.js +297 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.js +68 -0
  7. package/dist/interfaces/ILogger.d.ts +8 -0
  8. package/dist/interfaces/ILogger.js +4 -0
  9. package/dist/interfaces/IMcpTool.d.ts +7 -0
  10. package/dist/interfaces/IMcpTool.js +3 -0
  11. package/dist/logging/ConsoleLogger.d.ts +16 -0
  12. package/dist/logging/ConsoleLogger.js +45 -0
  13. package/dist/logging/LoggerFactory.d.ts +9 -0
  14. package/dist/logging/LoggerFactory.js +12 -0
  15. package/dist/server/McpConfig.d.ts +26 -0
  16. package/dist/server/McpConfig.js +93 -0
  17. package/dist/server/McpHandler.d.ts +12 -0
  18. package/dist/server/McpHandler.js +69 -0
  19. package/dist/server/McpServer.d.ts +15 -0
  20. package/dist/server/McpServer.js +49 -0
  21. package/dist/server/ToolRegistry.d.ts +22 -0
  22. package/dist/server/ToolRegistry.js +85 -0
  23. package/dist/tools/artifacts/GetArtifactController.d.ts +34 -0
  24. package/dist/tools/artifacts/GetArtifactController.js +397 -0
  25. package/dist/tools/artifacts/GetLatestController.d.ts +39 -0
  26. package/dist/tools/artifacts/GetLatestController.js +469 -0
  27. package/dist/tools/artifacts/ListVersionsController.d.ts +43 -0
  28. package/dist/tools/artifacts/ListVersionsController.js +530 -0
  29. package/dist/tools/artifacts/PublishArtifactController.d.ts +37 -0
  30. package/dist/tools/artifacts/PublishArtifactController.js +605 -0
  31. package/dist/tools/base/BaseToolController.d.ts +16 -0
  32. package/dist/tools/base/BaseToolController.js +32 -0
  33. package/dist/tools/core/DeleteArtifactTool.d.ts +11 -0
  34. package/dist/tools/core/DeleteArtifactTool.js +82 -0
  35. package/dist/tools/core/GetArtifactTool.d.ts +13 -0
  36. package/dist/tools/core/GetArtifactTool.js +125 -0
  37. package/dist/tools/core/GetArtifactVersionsTool.d.ts +11 -0
  38. package/dist/tools/core/GetArtifactVersionsTool.js +63 -0
  39. package/dist/tools/core/GetChunkTool.d.ts +11 -0
  40. package/dist/tools/core/GetChunkTool.js +56 -0
  41. package/dist/tools/core/ListArtifactsTool.d.ts +11 -0
  42. package/dist/tools/core/ListArtifactsTool.js +84 -0
  43. package/dist/tools/core/PublishArtifactFromFileTool.d.ts +15 -0
  44. package/dist/tools/core/PublishArtifactFromFileTool.js +256 -0
  45. package/dist/tools/core/PublishArtifactTool.d.ts +13 -0
  46. package/dist/tools/core/PublishArtifactTool.js +197 -0
  47. package/dist/tools/discovery/BrowseCategoriesController.d.ts +25 -0
  48. package/dist/tools/discovery/BrowseCategoriesController.js +400 -0
  49. package/dist/tools/discovery/FindByPurposeController.d.ts +12 -0
  50. package/dist/tools/discovery/FindByPurposeController.js +131 -0
  51. package/dist/tools/discovery/ListAuthorsController.d.ts +20 -0
  52. package/dist/tools/discovery/ListAuthorsController.js +274 -0
  53. package/dist/tools/discovery/SearchArtifactsController.d.ts +14 -0
  54. package/dist/tools/discovery/SearchArtifactsController.js +226 -0
  55. package/dist/tools/list/ListNamespaceController.d.ts +1 -0
  56. package/dist/tools/list/ListNamespaceController.js +8 -0
  57. package/dist/tools/navigation/ExploreNamespaceController.d.ts +35 -0
  58. package/dist/tools/navigation/ExploreNamespaceController.js +548 -0
  59. package/dist/tools/utility/AuthorIndexTool.d.ts +11 -0
  60. package/dist/tools/utility/AuthorIndexTool.js +48 -0
  61. package/dist/tools/utility/HealthCheckController.d.ts +11 -0
  62. package/dist/tools/utility/HealthCheckController.js +56 -0
  63. package/dist/tools/utility/ListRepositoriesTool.d.ts +11 -0
  64. package/dist/tools/utility/ListRepositoriesTool.js +70 -0
  65. package/dist/tools/utility/QuickstartTool.d.ts +11 -0
  66. package/dist/tools/utility/QuickstartTool.js +36 -0
  67. package/dist/tools/utility/ValidatePathController.d.ts +30 -0
  68. package/dist/tools/utility/ValidatePathController.js +465 -0
  69. package/dist/types/UcmApiTypes.d.ts +40 -0
  70. package/dist/types/UcmApiTypes.js +4 -0
  71. package/dist/utils/McpErrorHandler.d.ts +25 -0
  72. package/dist/utils/McpErrorHandler.js +67 -0
  73. package/dist/utils/PathUtils.d.ts +61 -0
  74. package/dist/utils/PathUtils.js +178 -0
  75. package/dist/utils/ResponseChunker.d.ts +25 -0
  76. package/dist/utils/ResponseChunker.js +79 -0
  77. package/dist/utils/ValidationUtils.d.ts +10 -0
  78. package/dist/utils/ValidationUtils.js +50 -0
  79. package/package.json +37 -0
  80. package/package.json.backup +37 -0
@@ -0,0 +1,82 @@
1
+ import { BaseToolController } from '../base/BaseToolController.js';
2
+ export class DeleteArtifactTool extends BaseToolController {
3
+ constructor(ucmClient, logger, publishingAuthorId) {
4
+ super(ucmClient, logger, publishingAuthorId);
5
+ }
6
+ get name() {
7
+ return 'mcp_ucm_delete_artifact';
8
+ }
9
+ get description() {
10
+ return 'Delete a UCM artifact by path and version. This action cannot be undone. Only the latest or specified version is deleted.';
11
+ }
12
+ get inputSchema() {
13
+ return {
14
+ type: 'object',
15
+ properties: {
16
+ author: {
17
+ type: 'string',
18
+ description: `Author name (e.g., ${this.publishingAuthorId || '01234567890'})`,
19
+ minLength: 1,
20
+ maxLength: 50
21
+ },
22
+ repository: {
23
+ type: 'string',
24
+ description: 'Repository name (e.g., "main")',
25
+ minLength: 1,
26
+ maxLength: 50
27
+ },
28
+ category: {
29
+ type: 'string',
30
+ description: 'Category name (e.g., "commands")',
31
+ minLength: 1,
32
+ maxLength: 50
33
+ },
34
+ subcategory: {
35
+ type: 'string',
36
+ description: 'Subcategory name (e.g., "user")',
37
+ minLength: 1,
38
+ maxLength: 50
39
+ },
40
+ filename: {
41
+ type: 'string',
42
+ description: 'Filename with optional version suffix (e.g., "CreateUserCommand.ts" or "CreateUserCommand.ts@1.0.0")',
43
+ minLength: 1,
44
+ maxLength: 150
45
+ }
46
+ },
47
+ required: ['author', 'repository', 'category', 'subcategory', 'filename']
48
+ };
49
+ }
50
+ async handleExecute(params) {
51
+ const { author, repository, category, subcategory, filename } = params;
52
+ this.logger.debug('DeleteArtifactTool', `Deleting artifact: ${author}/${repository}/${category}/${subcategory}/${filename}`);
53
+ try {
54
+ // Parse filename to extract version if present
55
+ const parts = filename.split('@');
56
+ const actualFilename = parts[0];
57
+ const version = parts.length > 1 ? parts[1] : undefined;
58
+ // Delete artifact from API and capture the response
59
+ const deleteResponse = await this.ucmClient.deleteArtifact(author, repository, category, subcategory, actualFilename, version);
60
+ const path = `${author}/${repository}/${category}/${subcategory}/${filename}`;
61
+ this.logger.info('DeleteArtifactTool', `Artifact deleted successfully: ${path}`);
62
+ // Use actual response data from the server instead of hardcoded values
63
+ return {
64
+ success: deleteResponse.success || true,
65
+ message: `Artifact deleted successfully`,
66
+ author,
67
+ repository,
68
+ category,
69
+ subcategory,
70
+ filename: deleteResponse.filename || actualFilename,
71
+ version: deleteResponse.version, // Use actual version that was deleted from server
72
+ path,
73
+ deletedAt: deleteResponse.deletedAt || new Date().toISOString()
74
+ };
75
+ }
76
+ catch (error) {
77
+ this.logger.error('DeleteArtifactTool', `Failed to delete artifact: ${author}/${repository}/${category}/${subcategory}/${filename}`, '', error);
78
+ throw error;
79
+ }
80
+ }
81
+ }
82
+ //# sourceMappingURL=DeleteArtifactTool.js.map
@@ -0,0 +1,13 @@
1
+ import { BaseToolController } from '../base/BaseToolController.js';
2
+ import { UcmApiClient } from '../../clients/UcmApiClient.js';
3
+ import { ILogger } from '../../interfaces/ILogger.js';
4
+ export declare class GetArtifactTool extends BaseToolController {
5
+ private trustedAuthors;
6
+ constructor(ucmClient: UcmApiClient, logger: ILogger, publishingAuthorId?: string, trustedAuthors?: string[]);
7
+ get name(): string;
8
+ get description(): string;
9
+ get inputSchema(): any;
10
+ protected handleExecute(params: any): Promise<any>;
11
+ private detectMimeType;
12
+ }
13
+ //# sourceMappingURL=GetArtifactTool.d.ts.map
@@ -0,0 +1,125 @@
1
+ import { BaseToolController } from '../base/BaseToolController.js';
2
+ import { ResponseChunker } from '../../utils/ResponseChunker.js';
3
+ import { parsePath } from '../../utils/PathUtils.js';
4
+ export class GetArtifactTool extends BaseToolController {
5
+ trustedAuthors;
6
+ constructor(ucmClient, logger, publishingAuthorId, trustedAuthors = []) {
7
+ super(ucmClient, logger, publishingAuthorId);
8
+ this.trustedAuthors = trustedAuthors;
9
+ }
10
+ get name() {
11
+ return 'mcp_ucm_get_artifact';
12
+ }
13
+ get description() {
14
+ return 'Retrieve UCM artifact content with metadata. Large files are automatically chunked.';
15
+ }
16
+ get inputSchema() {
17
+ return {
18
+ type: 'object',
19
+ properties: {
20
+ path: {
21
+ type: 'string',
22
+ description: `Full artifact path with optional version (e.g., "${this.publishingAuthorId || '1234567890'}/main/commands/user/CreateUserCommand.ts" or "${this.publishingAuthorId || '1234567890'}/main/commands/user/CreateUserCommand.ts@1.0.0")`,
23
+ minLength: 1,
24
+ maxLength: 200
25
+ },
26
+ includeMetadata: {
27
+ type: 'boolean',
28
+ description: 'Include artifact metadata in response',
29
+ default: true
30
+ }
31
+ },
32
+ required: ['path']
33
+ };
34
+ }
35
+ async handleExecute(params) {
36
+ let { path, includeMetadata = true } = params;
37
+ this.logger.debug('GetArtifactTool', `Retrieving artifact: ${path}`);
38
+ try {
39
+ // Parse the path to extract components
40
+ if (!path)
41
+ path = "";
42
+ const pathComponents = parsePath(path);
43
+ // Validate that path contains all required components including repository
44
+ if (!pathComponents.author || !pathComponents.repository || !pathComponents.category || !pathComponents.subcategory || !pathComponents.filename) {
45
+ throw new Error(`Path must include all components: author/repository/category/subcategory/filename.ext. Expected format: "author/repository/category/subcategory/filename.ext" or "author/repository/category/subcategory/filename.ext@version". Received: "${path}"`);
46
+ }
47
+ // Get artifact from API
48
+ const artifact = await this.ucmClient.getArtifact(pathComponents.author, pathComponents.repository, pathComponents.category, pathComponents.subcategory, pathComponents.filename, pathComponents.version);
49
+ // Extract content - it should always be a string in the API response
50
+ if (!artifact.content) {
51
+ throw new Error('Artifact has no content');
52
+ }
53
+ const content = artifact.content;
54
+ // Check if author is trusted
55
+ const author = artifact.metadata?.author || pathComponents.author;
56
+ const isTrusted = this.trustedAuthors.includes(author);
57
+ // Build response
58
+ const response = {
59
+ content,
60
+ path: artifact.path || path,
61
+ filename: pathComponents.filename // filename comes from parsed path
62
+ };
63
+ // Add security warning for untrusted authors
64
+ if (!isTrusted && this.publishingAuthorId && this.publishingAuthorId != pathComponents.author) {
65
+ response.securityWarning = `⚠️ SECURITY WARNING: This artifact is from author '${author}' who is not in your trusted authors list. Please review the code carefully before using it.`;
66
+ }
67
+ // Add metadata if requested
68
+ if (includeMetadata) {
69
+ response.metadata = {
70
+ id: artifact.id,
71
+ version: artifact.metadata?.version || pathComponents.version || 'latest',
72
+ name: artifact.metadata?.name,
73
+ description: artifact.metadata?.description,
74
+ author: author,
75
+ repository: pathComponents.repository,
76
+ category: artifact.metadata?.category || pathComponents.category,
77
+ subcategory: artifact.metadata?.subcategory || pathComponents.subcategory,
78
+ technology: artifact.metadata?.technology,
79
+ tags: artifact.metadata?.tags || [],
80
+ contractVersion: artifact.metadata?.contractVersion,
81
+ size: content.length,
82
+ mimeType: this.detectMimeType(pathComponents.filename),
83
+ lastUpdated: artifact.lastUpdated,
84
+ publishedAt: artifact.publishedAt,
85
+ };
86
+ }
87
+ // Apply chunking if needed
88
+ const chunkedResponse = ResponseChunker.chunk(response);
89
+ this.logger.info('GetArtifactTool', `Artifact retrieved: ${path}`, '', {
90
+ size: content.length,
91
+ chunked: chunkedResponse.chunk ? true : false
92
+ });
93
+ return chunkedResponse;
94
+ }
95
+ catch (error) {
96
+ this.logger.error('GetArtifactTool', `Failed to retrieve artifact: ${path}`, '', error);
97
+ throw error;
98
+ }
99
+ }
100
+ detectMimeType(filename) {
101
+ const ext = filename.split('.').pop()?.toLowerCase();
102
+ const mimeTypes = {
103
+ 'ts': 'application/typescript',
104
+ 'js': 'application/javascript',
105
+ 'json': 'application/json',
106
+ 'md': 'text/markdown',
107
+ 'txt': 'text/plain',
108
+ 'yaml': 'text/yaml',
109
+ 'yml': 'text/yaml',
110
+ 'html': 'text/html',
111
+ 'css': 'text/css',
112
+ 'py': 'text/x-python',
113
+ 'java': 'text/x-java',
114
+ 'cs': 'text/x-csharp',
115
+ 'go': 'text/x-go',
116
+ 'rs': 'text/x-rust',
117
+ 'cpp': 'text/x-c++',
118
+ 'c': 'text/x-c',
119
+ 'sh': 'text/x-shellscript',
120
+ 'xml': 'application/xml'
121
+ };
122
+ return mimeTypes[ext || ''] || 'text/plain';
123
+ }
124
+ }
125
+ //# sourceMappingURL=GetArtifactTool.js.map
@@ -0,0 +1,11 @@
1
+ import { BaseToolController } from '../base/BaseToolController.js';
2
+ import { UcmApiClient } from '../../clients/UcmApiClient.js';
3
+ import { ILogger } from '../../interfaces/ILogger.js';
4
+ export declare class GetArtifactVersionsTool extends BaseToolController {
5
+ constructor(ucmClient: UcmApiClient, logger: ILogger, publishingAuthorId?: string);
6
+ get name(): string;
7
+ get description(): string;
8
+ get inputSchema(): any;
9
+ protected handleExecute(params: any): Promise<any>;
10
+ }
11
+ //# sourceMappingURL=GetArtifactVersionsTool.d.ts.map
@@ -0,0 +1,63 @@
1
+ import { BaseToolController } from '../base/BaseToolController.js';
2
+ import { parsePath } from '../../utils/PathUtils.js';
3
+ export class GetArtifactVersionsTool extends BaseToolController {
4
+ constructor(ucmClient, logger, publishingAuthorId) {
5
+ super(ucmClient, logger, publishingAuthorId);
6
+ }
7
+ get name() {
8
+ return 'mcp_ucm_get_artifact_versions';
9
+ }
10
+ get description() {
11
+ return 'Get all available versions of a specific UCM artifact';
12
+ }
13
+ get inputSchema() {
14
+ return {
15
+ type: 'object',
16
+ properties: {
17
+ path: {
18
+ type: 'string',
19
+ description: `Full artifact path without version (e.g., "${this.publishingAuthorId || '01234567890'}/main/commands/user/CreateUserCommand.ts")`,
20
+ minLength: 1,
21
+ maxLength: 200
22
+ }
23
+ },
24
+ required: ['path']
25
+ };
26
+ }
27
+ async handleExecute(params) {
28
+ let { path } = params;
29
+ this.logger.debug('GetArtifactVersionsTool', `Retrieving versions for artifact: ${path}`);
30
+ try {
31
+ // Parse the path to extract components
32
+ if (!path)
33
+ path = "";
34
+ const pathComponents = parsePath(path);
35
+ // Validate that path contains all required components including repository
36
+ if (!pathComponents.author || !pathComponents.repository || !pathComponents.category ||
37
+ !pathComponents.subcategory || !pathComponents.filename) {
38
+ throw new Error(`Invalid artifact path. Expected format: {author}/{repository}/{category}/{subcategory}/{filename}. ` +
39
+ `Received: ${path}`);
40
+ }
41
+ // Get versions from API
42
+ const versions = await this.ucmClient.getArtifactVersions(pathComponents.author, pathComponents.repository, pathComponents.category, pathComponents.subcategory, pathComponents.filename);
43
+ // Return the versions data
44
+ return {
45
+ path,
46
+ author: pathComponents.author,
47
+ repository: pathComponents.repository,
48
+ category: pathComponents.category,
49
+ subcategory: pathComponents.subcategory,
50
+ filename: pathComponents.filename,
51
+ versions: versions
52
+ };
53
+ }
54
+ catch (error) {
55
+ this.logger.error('GetArtifactVersionsTool', 'Failed to retrieve artifact versions', error);
56
+ if (error.message?.includes('404') || error.message?.includes('not found')) {
57
+ throw new Error(`Artifact not found: ${path}`);
58
+ }
59
+ throw new Error(`Failed to retrieve artifact versions: ${error.message || 'Unknown error'}`);
60
+ }
61
+ }
62
+ }
63
+ //# sourceMappingURL=GetArtifactVersionsTool.js.map
@@ -0,0 +1,11 @@
1
+ import { BaseToolController } from '../base/BaseToolController.js';
2
+ import { UcmApiClient } from '../../clients/UcmApiClient.js';
3
+ import { ILogger } from '../../interfaces/ILogger.js';
4
+ export declare class GetChunkTool extends BaseToolController {
5
+ constructor(ucmClient: UcmApiClient, logger: ILogger, publishingAuthorId?: string);
6
+ get name(): string;
7
+ get description(): string;
8
+ get inputSchema(): any;
9
+ protected handleExecute(params: any): Promise<any>;
10
+ }
11
+ //# sourceMappingURL=GetChunkTool.d.ts.map
@@ -0,0 +1,56 @@
1
+ import { BaseToolController } from '../base/BaseToolController.js';
2
+ import { ResponseChunker } from '../../utils/ResponseChunker.js';
3
+ import { McpError, McpErrorCode } from '../../utils/McpErrorHandler.js';
4
+ export class GetChunkTool extends BaseToolController {
5
+ constructor(ucmClient, logger, publishingAuthorId) {
6
+ super(ucmClient, logger, publishingAuthorId);
7
+ }
8
+ get name() {
9
+ return 'mcp_ucm_get_chunk';
10
+ }
11
+ get description() {
12
+ return 'Retrieve the next chunk of a large UCM artifact response';
13
+ }
14
+ get inputSchema() {
15
+ return {
16
+ type: 'object',
17
+ properties: {
18
+ chunkId: {
19
+ type: 'string',
20
+ description: 'The chunk ID to retrieve',
21
+ minLength: 1
22
+ },
23
+ sequence: {
24
+ type: 'number',
25
+ description: 'The sequence number of the chunk to retrieve',
26
+ minimum: 0
27
+ }
28
+ },
29
+ required: ['chunkId', 'sequence']
30
+ };
31
+ }
32
+ async handleExecute(params) {
33
+ const { chunkId, sequence } = params;
34
+ this.logger.debug('GetChunkTool', `Retrieving chunk: ${chunkId} sequence ${sequence}`);
35
+ // Get chunk info first
36
+ const chunkInfo = ResponseChunker.getChunkInfo(chunkId);
37
+ if (!chunkInfo.exists) {
38
+ throw new McpError(McpErrorCode.InvalidParams, `Chunk with ID '${chunkId}' not found. It may have expired.`);
39
+ }
40
+ // Validate sequence range
41
+ if (sequence < 0 || (chunkInfo.total && sequence >= chunkInfo.total)) {
42
+ throw new McpError(McpErrorCode.InvalidParams, `Sequence ${sequence} is out of range. Valid range is 0-${(chunkInfo.total || 1) - 1}`);
43
+ }
44
+ // Get the chunk
45
+ const nextChunk = ResponseChunker.getNextChunk(chunkId, sequence);
46
+ if (!nextChunk) {
47
+ throw new McpError(McpErrorCode.InternalError, 'Failed to retrieve chunk');
48
+ }
49
+ this.logger.info('GetChunkTool', `Chunk retrieved: ${chunkId} sequence ${sequence}`, '', {
50
+ hasMore: nextChunk.hasMore,
51
+ total: nextChunk.chunk.total
52
+ });
53
+ return nextChunk;
54
+ }
55
+ }
56
+ //# sourceMappingURL=GetChunkTool.js.map
@@ -0,0 +1,11 @@
1
+ import { BaseToolController } from '../base/BaseToolController.js';
2
+ import { UcmApiClient } from '../../clients/UcmApiClient.js';
3
+ import { ILogger } from '../../interfaces/ILogger.js';
4
+ export declare class ListArtifactsTool extends BaseToolController {
5
+ constructor(ucmClient: UcmApiClient, logger: ILogger, publishingAuthorId?: string);
6
+ get name(): string;
7
+ get description(): string;
8
+ get inputSchema(): any;
9
+ protected handleExecute(params: any): Promise<any>;
10
+ }
11
+ //# sourceMappingURL=ListArtifactsTool.d.ts.map
@@ -0,0 +1,84 @@
1
+ import { BaseToolController } from '../base/BaseToolController.js';
2
+ import { parsePath } from '../../utils/PathUtils.js';
3
+ export class ListArtifactsTool extends BaseToolController {
4
+ constructor(ucmClient, logger, publishingAuthorId) {
5
+ super(ucmClient, logger, publishingAuthorId);
6
+ }
7
+ get name() {
8
+ return 'mcp_ucm_list_artifacts';
9
+ }
10
+ get description() {
11
+ return `List artifacts with exploratory browsing support. Can list author categories, subcategories, or artifacts depending on path depth. ${this.publishingAuthorId ? "Your author value is '" + this.publishingAuthorId + "'" : ''}`;
12
+ }
13
+ get inputSchema() {
14
+ return {
15
+ type: 'object',
16
+ properties: {
17
+ path: {
18
+ type: 'string',
19
+ description: `Exploratory path: empty string or omit for authors, "{author}" for repositories, "{author}/{repository}" for categories, "{author}/{repository}/{category}" for subcategories, or "{author}/{repository}/{category}/{subcategory}" for artifacts. Eg; ${this.publishingAuthorId}/main/commands/user`,
20
+ minLength: 0,
21
+ maxLength: 200
22
+ },
23
+ offset: {
24
+ type: 'number',
25
+ description: 'Number of items to skip for pagination (default: 0)',
26
+ minimum: 0
27
+ },
28
+ limit: {
29
+ type: 'number',
30
+ description: 'Maximum number of items to return (default: 20, max: 100)',
31
+ minimum: 1,
32
+ maximum: 100
33
+ }
34
+ },
35
+ required: []
36
+ };
37
+ }
38
+ async handleExecute(params) {
39
+ let { path, offset, limit } = params;
40
+ if (!path)
41
+ path = "";
42
+ this.logger.debug('ListArtifactsTool', `Exploring path: ${path} (offset: ${offset || 0}, limit: ${limit || 'default'})`);
43
+ try {
44
+ // Parse the path to extract components
45
+ const pathComponents = parsePath(path);
46
+ const pathSegments = path.split('/').filter(Boolean);
47
+ // Call API based on path depth for exploratory browsing
48
+ const response = await this.ucmClient.listArtifacts(pathComponents.author, pathComponents.repository, pathComponents.category, pathComponents.subcategory, offset, limit);
49
+ // Determine what we're listing based on path depth (4-level structure)
50
+ let listingType = 'artifacts';
51
+ if (pathSegments.length == 0) {
52
+ listingType = 'authors';
53
+ }
54
+ else if (pathSegments.length === 1) {
55
+ listingType = 'repositories';
56
+ }
57
+ else if (pathSegments.length === 2) {
58
+ listingType = 'categories';
59
+ }
60
+ else if (pathSegments.length === 3) {
61
+ listingType = 'subcategories';
62
+ }
63
+ // For MVP, validate repository is 'main' if provided
64
+ if (pathSegments.length >= 2 && pathComponents.repository && pathComponents.repository !== 'main') {
65
+ throw new Error(`Repository must be 'main' for MVP. Received: "${pathComponents.repository}"`);
66
+ }
67
+ this.logger.info('ListArtifactsTool', `Listed ${response.data.length} ${listingType} in: ${path}`);
68
+ // Return the full response with pagination metadata and context
69
+ return {
70
+ path,
71
+ listingType,
72
+ data: response.data,
73
+ pagination: response.pagination,
74
+ hasMore: response.pagination.offset + response.pagination.limit < response.pagination.total,
75
+ _links: response._links
76
+ };
77
+ }
78
+ catch (error) {
79
+ this.logger.error('ListArtifactsTool', `Failed to explore path: ${path}`, '', error);
80
+ throw error;
81
+ }
82
+ }
83
+ }
84
+ //# sourceMappingURL=ListArtifactsTool.js.map
@@ -0,0 +1,15 @@
1
+ import { BaseToolController } from '../base/BaseToolController.js';
2
+ import { UcmApiClient } from '../../clients/UcmApiClient.js';
3
+ import { ILogger } from '../../interfaces/ILogger.js';
4
+ export declare class PublishArtifactFromFileTool extends BaseToolController {
5
+ constructor(ucmClient: UcmApiClient, logger: ILogger, publishingAuthorId?: string);
6
+ get name(): string;
7
+ get description(): string;
8
+ get inputSchema(): any;
9
+ protected handleExecute(params: any): Promise<any>;
10
+ protected validateParams(params: any): void;
11
+ private parseFileUri;
12
+ private readFileContent;
13
+ private detectMimeType;
14
+ }
15
+ //# sourceMappingURL=PublishArtifactFromFileTool.d.ts.map