Skip to content

Commit 2c60da6

Browse files
EPMRPP-109176 || MCP. Tools. Add tool, update defect types by item ids
1 parent 178b1e7 commit 2c60da6

File tree

6 files changed

+83
-7
lines changed

6 files changed

+83
-7
lines changed

cmd/reportportal-mcp-server/main.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ func main() {
5959
Name: "project",
6060
Required: false,
6161
Sources: cli.EnvVars("RP_PROJECT"),
62+
Value: "",
6263
Usage: "ReportPortal project name",
6364
},
6465
&cli.StringFlag{
@@ -238,6 +239,7 @@ func newMCPServer(cmd *cli.Command) (*server.MCPServer, *mcpreportportal.Analyti
238239
token := cmd.String("token") // API token
239240
host := cmd.String("rp-host") // ReportPortal host URL
240241
userID := cmd.String("user-id") // Unified user ID for analytics
242+
project := cmd.String("project") // ReportPortal project name
241243
analyticsAPISecret := mcpreportportal.GetAnalyticArg() // Analytics API secret
242244
analyticsOff := cmd.Bool("analytics-off") // Disable analytics flag
243245

@@ -252,6 +254,7 @@ func newMCPServer(cmd *cli.Command) (*server.MCPServer, *mcpreportportal.Analyti
252254
hostUrl,
253255
token,
254256
userID,
257+
project,
255258
analyticsAPISecret,
256259
!analyticsOff, // Convert analyticsOff to analyticsOn
257260
)

internal/reportportal/http_server.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ func (hs *HTTPServer) initializeTools() error {
140140
rpClient.APIClient.GetConfig().Middleware = QueryParamsMiddleware
141141

142142
// Add launch management tools with analytics
143-
launches := NewLaunchResources(rpClient, hs.analytics)
143+
launches := NewLaunchResources(rpClient, hs.analytics, "")
144144

145145
hs.mcpServer.AddTool(launches.toolGetLaunches())
146146
hs.mcpServer.AddTool(launches.toolGetLastLaunchByName())
@@ -153,7 +153,7 @@ func (hs *HTTPServer) initializeTools() error {
153153
hs.mcpServer.AddResourceTemplate(launches.resourceLaunch())
154154

155155
// Add test item tools
156-
testItems := NewTestItemResources(rpClient, hs.analytics)
156+
testItems := NewTestItemResources(rpClient, hs.analytics, "")
157157

158158
hs.mcpServer.AddTool(testItems.toolGetTestItemById())
159159
hs.mcpServer.AddTool(testItems.toolGetTestItemsByFilter())

internal/reportportal/items.go

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/mark3labs/mcp-go/mcp"
1313
"github.com/mark3labs/mcp-go/server"
1414
"github.com/reportportal/goRP/v5/pkg/gorp"
15+
"github.com/reportportal/goRP/v5/pkg/openapi"
1516
"github.com/yosida95/uritemplate/v3"
1617
)
1718

@@ -25,11 +26,13 @@ type TestItemResources struct {
2526
func NewTestItemResources(
2627
client *gorp.Client,
2728
analytics *Analytics,
29+
project string,
2830
) *TestItemResources {
2931
return &TestItemResources{
3032
client: client,
3133
projectParameter: mcp.WithString("project", // Parameter for specifying the project name)
3234
mcp.Description("Project name"),
35+
mcp.DefaultString(project),
3336
),
3437
analytics: analytics,
3538
}
@@ -626,7 +629,8 @@ func (lr *TestItemResources) toolGetProjectDefectTypes() (mcp.Tool, server.ToolH
626629
"get_project_defect_types",
627630
// Tool metadata
628631
mcp.WithDescription(
629-
"Get all defect types for a specific project, returns a JSON which contains a list of defect types in the 'configuration/subtypes' array",
632+
"Get all defect types for a specific project, returns a JSON which contains a list of defect types in the 'configuration/subtypes' array and represents the defect type ID. "+
633+
"Example: { \"NO_DEFECT\": { \"locator\": \"nd001\" } NO_DEFECT - defect type name, nd001 - defect type unique id }, ",
630634
),
631635
lr.projectParameter,
632636
), lr.analytics.WithAnalytics("get_project_defect_types", func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
@@ -646,3 +650,69 @@ func (lr *TestItemResources) toolGetProjectDefectTypes() (mcp.Tool, server.ToolH
646650
return readResponseBody(response)
647651
})
648652
}
653+
654+
// toolUpdateTestItemDefectType creates a tool to update the defect type for a specific test items.
655+
func (lr *TestItemResources) toolUpdateTestItemDefectType() (mcp.Tool, server.ToolHandlerFunc) {
656+
return mcp.NewTool("update_test_item_defect_type",
657+
// Tool metadata
658+
mcp.WithDescription("Update test item defect type"),
659+
lr.projectParameter,
660+
mcp.WithArray("test_item_ids", // Parameter for specifying the array of test item IDs
661+
mcp.Description("Array of test item IDs"),
662+
mcp.Required(),
663+
),
664+
mcp.WithString(
665+
"defect_type_id", // Parameter for specifying the defect type ID
666+
mcp.Description(
667+
"Defect Type ID, all possible values can be received from the tool 'get_project_defect_types', \"locator\" is a unique identifier of the defect type. "+
668+
"Example: \"NO_DEFECT\": { \"locator\": \"nd001\" } NO_DEFECT - defect type name, nd001 - defect type unique id",
669+
),
670+
mcp.Required(),
671+
),
672+
), lr.analytics.WithAnalytics("update_test_item_defect_type", func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
673+
project, err := extractProject(ctx, request)
674+
if err != nil {
675+
return mcp.NewToolResultError(err.Error()), nil
676+
}
677+
678+
// Extract the "defect_type_id" parameter from the request
679+
defectTypeId, err := request.RequireString("defect_type_id")
680+
if err != nil {
681+
return mcp.NewToolResultError(err.Error()), nil
682+
}
683+
// Extract the "test_item_ids" parameter from the request
684+
testItemIdStrs, err := request.RequireStringSlice("test_item_ids")
685+
if err != nil {
686+
return mcp.NewToolResultError(err.Error()), nil
687+
}
688+
689+
// Build the list of issues
690+
issues := make([]openapi.IssueDefinition, 0, len(testItemIdStrs))
691+
for _, testItemIdStr := range testItemIdStrs {
692+
testItemId, err := strconv.ParseInt(testItemIdStr, 10, 64)
693+
if err != nil {
694+
return mcp.NewToolResultError(err.Error()), nil
695+
}
696+
issues = append(issues, openapi.IssueDefinition{
697+
TestItemId: testItemId,
698+
Issue: openapi.Issue{
699+
IssueType: defectTypeId,
700+
},
701+
})
702+
}
703+
704+
apiRequest := lr.client.TestItemAPI.DefineTestItemIssueType(ctx, project).
705+
DefineIssueRQ(openapi.DefineIssueRQ{
706+
Issues: issues,
707+
})
708+
709+
// Execute the request
710+
_, response, err := apiRequest.Execute()
711+
if err != nil {
712+
return mcp.NewToolResultError(extractResponseError(err, response)), nil
713+
}
714+
715+
// Return the serialized testItem as a text result
716+
return readResponseBody(response)
717+
})
718+
}

internal/reportportal/launches.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@ type LaunchResources struct {
2525
func NewLaunchResources(
2626
client *gorp.Client,
2727
analytics *Analytics,
28+
project string,
2829
) *LaunchResources {
2930
return &LaunchResources{
3031
client: client,
3132
projectParameter: mcp.WithString("project", // Parameter for specifying the project name)
3233
mcp.Description("Project name"),
34+
mcp.DefaultString(project),
3335
),
3436
analytics: analytics,
3537
}

internal/reportportal/launches_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ func TestListLaunchesTool(t *testing.T) {
4343
srv := mcptest.NewUnstartedServer(t)
4444

4545
serverURL, _ := url.Parse(mockServer.URL)
46-
launchTools := NewLaunchResources(gorp.NewClient(serverURL, ""), nil)
46+
launchTools := NewLaunchResources(gorp.NewClient(serverURL, ""), nil, "")
4747
srv.AddTool(launchTools.toolGetLaunches())
4848

4949
err := srv.Start(ctx)

internal/reportportal/server.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func NewServer(
2020
version string,
2121
hostUrl *url.URL,
2222
token,
23-
userID, analyticsAPISecret string,
23+
userID, project, analyticsAPISecret string,
2424
analyticsOn bool,
2525
) (*server.MCPServer, *Analytics, error) {
2626
s := server.NewMCPServer(
@@ -47,7 +47,7 @@ func NewServer(
4747
}
4848
}
4949

50-
launches := NewLaunchResources(rpClient, analytics)
50+
launches := NewLaunchResources(rpClient, analytics, project)
5151
s.AddTool(launches.toolGetLaunches())
5252
s.AddTool(launches.toolGetLastLaunchByName())
5353
s.AddTool(launches.toolForceFinishLaunch())
@@ -57,13 +57,14 @@ func NewServer(
5757
s.AddTool(launches.toolRunQualityGate())
5858
s.AddResourceTemplate(launches.resourceLaunch())
5959

60-
testItems := NewTestItemResources(rpClient, analytics)
60+
testItems := NewTestItemResources(rpClient, analytics, project)
6161
s.AddTool(testItems.toolGetTestItemById())
6262
s.AddTool(testItems.toolGetTestItemsByFilter())
6363
s.AddTool(testItems.toolGetTestItemLogsByFilter())
6464
s.AddTool(testItems.toolGetTestItemAttachment())
6565
s.AddTool(testItems.toolGetTestSuitesByFilter())
6666
s.AddTool(testItems.toolGetProjectDefectTypes())
67+
s.AddTool(testItems.toolUpdateTestItemDefectType())
6768
s.AddResourceTemplate(testItems.resourceTestItem())
6869

6970
prompts, err := readPrompts(promptFiles, "prompts")

0 commit comments

Comments
 (0)