@@ -20,29 +20,26 @@ func GetCcmOverviewTool(config *config.Config, client *client.CloudCostManagemen
20
20
defaultEndTime := utils .CurrentMMDDYYYY ();
21
21
return mcp .NewTool ("get_ccm_overview" ,
22
22
mcp .WithDescription ("Get an overview for an specific account in Harness Cloud Cost Management" ),
23
- mcp .WithString ("accountIdentifier" ,
24
- mcp .Description ("The account identifier" ),
25
- ),
26
23
mcp .WithString ("startTime" ,
24
+ mcp .Required (),
27
25
mcp .DefaultString (defaultStartTime ),
28
26
mcp .Description ("Start time of the period in format MM/DD/YYYY. (e.g. 10/30/2025)" ),
29
27
),
30
28
mcp .WithString ("endTime" ,
29
+ mcp .Required (),
31
30
mcp .DefaultString (defaultEndTime ),
32
31
mcp .Description ("End time of the period in format MM/DD/YYYY. (e.g. 10/30/2025)" ),
33
32
),
34
33
mcp .WithString ("groupBy" ,
35
- mcp .Description ("Optional type to group by period" ),
34
+ mcp .Required (),
35
+ mcp .Description ("Type to group by period" ),
36
36
mcp .DefaultString (dto .PeriodTypeHour ),
37
37
mcp .Enum (dto .PeriodTypeHour , dto .PeriodTypeDay , dto .PeriodTypeMonth , dto .PeriodTypeWeek , dto .PeriodTypeQuarter , dto .PeriodTypeYear ),
38
38
),
39
39
WithScope (config , false ),
40
40
),
41
41
func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
42
- accID , err := OptionalParam [string ](request , "accountIdentifier" )
43
- if accID == "" {
44
- accID , err = getAccountID (config , request )
45
- }
42
+ accountId , err := getAccountID (config , request )
46
43
if err != nil {
47
44
return mcp .NewToolResultError (err .Error ()), nil
48
45
}
@@ -64,7 +61,7 @@ func GetCcmOverviewTool(config *config.Config, client *client.CloudCostManagemen
64
61
return mcp .NewToolResultError (err .Error ()), nil
65
62
}
66
63
67
- data , err := client .GetOverview (ctx , accID , startTime , endTime , groupBy )
64
+ data , err := client .GetOverview (ctx , accountId , startTime , endTime , groupBy )
68
65
if err != nil {
69
66
return nil , fmt .Errorf ("failed to get CCM Overview: %w" , err )
70
67
}
@@ -80,9 +77,6 @@ func GetCcmOverviewTool(config *config.Config, client *client.CloudCostManagemen
80
77
func ListCcmCostCategoriesTool (config * config.Config , client * client.CloudCostManagementService ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
81
78
return mcp .NewTool ("list_ccm_cost_categories" ,
82
79
mcp .WithDescription ("List the cost categories for an account in Harness Cloud Cost Management" ),
83
- mcp .WithString ("account_id" ,
84
- mcp .Description ("The account identifier" ),
85
- ),
86
80
mcp .WithString ("cost_category" ,
87
81
mcp .Description ("Optional to search for specific category" ),
88
82
),
@@ -92,10 +86,7 @@ func ListCcmCostCategoriesTool(config *config.Config, client *client.CloudCostMa
92
86
WithScope (config , false ),
93
87
),
94
88
func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
95
- accountId , err := OptionalParam [string ](request , "accountIdentifier" )
96
- if accountId == "" {
97
- accountId , err = getAccountID (config , request )
98
- }
89
+ accountId , err := getAccountID (config , request )
99
90
if err != nil {
100
91
return mcp .NewToolResultError (err .Error ()), nil
101
92
}
@@ -104,7 +95,7 @@ func ListCcmCostCategoriesTool(config *config.Config, client *client.CloudCostMa
104
95
params .AccountIdentifier = accountId
105
96
106
97
// Handle cost category parameter
107
- costCategory , ok , err := OptionalParamOK [string ](request , "costCategory " )
98
+ costCategory , ok , err := OptionalParamOK [string ](request , "cost_category " )
108
99
if err != nil {
109
100
return mcp .NewToolResultError (err .Error ()), nil
110
101
}
@@ -113,7 +104,7 @@ func ListCcmCostCategoriesTool(config *config.Config, client *client.CloudCostMa
113
104
}
114
105
115
106
// Handle search parameter
116
- searchTerm , ok , err := OptionalParamOK [string ](request , "search " )
107
+ searchTerm , ok , err := OptionalParamOK [string ](request , "search_term " )
117
108
if err != nil {
118
109
return mcp .NewToolResultError (err .Error ()), nil
119
110
}
@@ -143,9 +134,6 @@ func ListCcmCostCategoriesTool(config *config.Config, client *client.CloudCostMa
143
134
func ListCcmCostCategoriesDetailTool (config * config.Config , client * client.CloudCostManagementService ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
144
135
return mcp .NewTool ("list_ccm_cost_categories_detail" ,
145
136
mcp .WithDescription ("List the cost categories with advanced options in Harness Cloud Cost Management" ),
146
- mcp .WithString ("account_id" ,
147
- mcp .Description ("The account identifier" ),
148
- ),
149
137
mcp .WithString ("search_key" ,
150
138
mcp .Description ("Optional search key to filter cost categories" ),
151
139
),
@@ -169,10 +157,7 @@ func ListCcmCostCategoriesDetailTool(config *config.Config, client *client.Cloud
169
157
WithScope (config , false ),
170
158
),
171
159
func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
172
- accountId , err := OptionalParam [string ](request , "account_id" )
173
- if accountId == "" {
174
- accountId , err = getAccountID (config , request )
175
- }
160
+ accountId , err := getAccountID (config , request )
176
161
if err != nil {
177
162
return mcp .NewToolResultError (err .Error ()), nil
178
163
}
@@ -244,11 +229,57 @@ func ListCcmCostCategoriesDetailTool(config *config.Config, client *client.Cloud
244
229
}
245
230
}
246
231
232
+ func GetCcmCostCategoryTool (config * config.Config , client * client.CloudCostManagementService ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
233
+ return mcp .NewTool ("get_ccm_cost_category" ,
234
+ mcp .WithDescription ("Retrieve the details of a cost category by its ID from a specific account in Harness Cloud Cost Management." ),
235
+ mcp .WithString ("id" ,
236
+ mcp .Description ("Required Cost Category ID to retrieve a specific cost category" ),
237
+ mcp .Required (),
238
+ ),
239
+ WithScope (config , false ),
240
+ ),
241
+ func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
242
+ accountId , err := getAccountID (config , request )
243
+ if err != nil {
244
+ return mcp .NewToolResultError (err .Error ()), nil
245
+ }
246
+
247
+ params := & dto.CCMGetCostCategoryOptions {}
248
+ params .AccountIdentifier = accountId
249
+ // Handle cost category parameter
250
+ costCategoryId , ok , err := OptionalParamOK [string ](request , "id" )
251
+ if err != nil {
252
+ return mcp .NewToolResultError (err .Error ()), nil
253
+ }
254
+ if ok && costCategoryId != "" {
255
+ params .CostCategoryId = costCategoryId
256
+ }
257
+ scope , err := fetchScope (config , request , false )
258
+ if err != nil {
259
+ return mcp .NewToolResultError (err .Error ()), nil
260
+ }
261
+
262
+ data , err := client .GetCostCategory (ctx , scope , params )
263
+ if err != nil {
264
+ return nil , fmt .Errorf ("failed to get CCM Cost Categories: %w" , err )
265
+ }
266
+
267
+ r , err := json .Marshal (data )
268
+ if err != nil {
269
+ return nil , fmt .Errorf ("failed to marshal CCM Cost Category: %w" , err )
270
+ }
271
+
272
+ return mcp .NewToolResultText (string (r )), nil
273
+ }
274
+ }
275
+
247
276
// getAccountID retrieves AccountID from the config file
248
277
func getAccountID (config * config.Config , request mcp.CallToolRequest ) (string , error ) {
249
- scope , scopeErr := fetchScope (config , request , true )
250
- if scopeErr != nil {
251
- return "" , nil
278
+ scope , _ := fetchScope (config , request , true )
279
+ // Error ignored because it can be related to project or org id
280
+ // which are not required for CCM
281
+ if scope .AccountID != "" {
282
+ return scope .AccountID , nil
252
283
}
253
- return scope . AccountID , nil
284
+ return "" , fmt . Errorf ( "Account ID is required" )
254
285
}
0 commit comments