6
6
"fmt"
7
7
"io"
8
8
"net/http"
9
+ "strconv"
9
10
"strings"
10
11
11
12
"github.com/github/github-mcp-server/pkg/translations"
@@ -236,10 +237,10 @@ func ListWorkflowRuns(getClient GetClientFn, t translations.TranslationHelperFun
236
237
}
237
238
}
238
239
239
- // RunWorkflow creates a tool to run an Actions workflow by workflow ID
240
+ // RunWorkflow creates a tool to run an Actions workflow
240
241
func RunWorkflow (getClient GetClientFn , t translations.TranslationHelperFunc ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
241
242
return mcp .NewTool ("run_workflow" ,
242
- mcp .WithDescription (t ("TOOL_RUN_WORKFLOW_DESCRIPTION" , "Run an Actions workflow by workflow ID" )),
243
+ mcp .WithDescription (t ("TOOL_RUN_WORKFLOW_DESCRIPTION" , "Run an Actions workflow by workflow ID or filename " )),
243
244
mcp .WithToolAnnotation (mcp.ToolAnnotation {
244
245
Title : t ("TOOL_RUN_WORKFLOW_USER_TITLE" , "Run workflow" ),
245
246
ReadOnlyHint : ToBoolPtr (false ),
@@ -252,9 +253,9 @@ func RunWorkflow(getClient GetClientFn, t translations.TranslationHelperFunc) (t
252
253
mcp .Required (),
253
254
mcp .Description (DescriptionRepositoryName ),
254
255
),
255
- mcp .WithNumber ("workflow_id" ,
256
+ mcp .WithString ("workflow_id" ,
256
257
mcp .Required (),
257
- mcp .Description ("The workflow ID (numeric identifier )" ),
258
+ mcp .Description ("The workflow ID (numeric) or workflow file name (e.g., main.yml, ci.yaml )" ),
258
259
),
259
260
mcp .WithString ("ref" ,
260
261
mcp .Required (),
@@ -273,11 +274,10 @@ func RunWorkflow(getClient GetClientFn, t translations.TranslationHelperFunc) (t
273
274
if err != nil {
274
275
return mcp .NewToolResultError (err .Error ()), nil
275
276
}
276
- workflowIDInt , err := RequiredInt (request , "workflow_id" )
277
+ workflowID , err := RequiredParam [ string ] (request , "workflow_id" )
277
278
if err != nil {
278
279
return mcp .NewToolResultError (err .Error ()), nil
279
280
}
280
- workflowID := int64 (workflowIDInt )
281
281
ref , err := RequiredParam [string ](request , "ref" )
282
282
if err != nil {
283
283
return mcp .NewToolResultError (err .Error ()), nil
@@ -301,105 +301,26 @@ func RunWorkflow(getClient GetClientFn, t translations.TranslationHelperFunc) (t
301
301
Inputs : inputs ,
302
302
}
303
303
304
- // Convert workflow ID to string format for the API call
305
- workflowIDStr := fmt .Sprintf ("%d" , workflowID )
306
- resp , err := client .Actions .CreateWorkflowDispatchEventByFileName (ctx , owner , repo , workflowIDStr , event )
307
- if err != nil {
308
- return nil , fmt .Errorf ("failed to run workflow: %w" , err )
309
- }
310
- defer func () { _ = resp .Body .Close () }()
311
-
312
- result := map [string ]any {
313
- "message" : "Workflow run has been queued" ,
314
- "workflow_id" : workflowID ,
315
- "ref" : ref ,
316
- "inputs" : inputs ,
317
- "status" : resp .Status ,
318
- "status_code" : resp .StatusCode ,
319
- }
320
-
321
- r , err := json .Marshal (result )
322
- if err != nil {
323
- return nil , fmt .Errorf ("failed to marshal response: %w" , err )
324
- }
325
-
326
- return mcp .NewToolResultText (string (r )), nil
327
- }
328
- }
329
-
330
- // RunWorkflowByFileName creates a tool to run an Actions workflow by filename
331
- func RunWorkflowByFileName (getClient GetClientFn , t translations.TranslationHelperFunc ) (tool mcp.Tool , handler server.ToolHandlerFunc ) {
332
- return mcp .NewTool ("run_workflow_by_filename" ,
333
- mcp .WithDescription (t ("TOOL_RUN_WORKFLOW_BY_FILENAME_DESCRIPTION" , "Run an Actions workflow by workflow filename" )),
334
- mcp .WithToolAnnotation (mcp.ToolAnnotation {
335
- Title : t ("TOOL_RUN_WORKFLOW_BY_FILENAME_USER_TITLE" , "Run workflow by filename" ),
336
- ReadOnlyHint : ToBoolPtr (false ),
337
- }),
338
- mcp .WithString ("owner" ,
339
- mcp .Required (),
340
- mcp .Description (DescriptionRepositoryOwner ),
341
- ),
342
- mcp .WithString ("repo" ,
343
- mcp .Required (),
344
- mcp .Description (DescriptionRepositoryName ),
345
- ),
346
- mcp .WithString ("workflow_file" ,
347
- mcp .Required (),
348
- mcp .Description ("The workflow file name (e.g., main.yml, ci.yaml)" ),
349
- ),
350
- mcp .WithString ("ref" ,
351
- mcp .Required (),
352
- mcp .Description ("The git reference for the workflow. The reference can be a branch or tag name." ),
353
- ),
354
- mcp .WithObject ("inputs" ,
355
- mcp .Description ("Inputs the workflow accepts" ),
356
- ),
357
- ),
358
- func (ctx context.Context , request mcp.CallToolRequest ) (* mcp.CallToolResult , error ) {
359
- owner , err := RequiredParam [string ](request , "owner" )
360
- if err != nil {
361
- return mcp .NewToolResultError (err .Error ()), nil
362
- }
363
- repo , err := RequiredParam [string ](request , "repo" )
364
- if err != nil {
365
- return mcp .NewToolResultError (err .Error ()), nil
366
- }
367
- workflowFile , err := RequiredParam [string ](request , "workflow_file" )
368
- if err != nil {
369
- return mcp .NewToolResultError (err .Error ()), nil
370
- }
371
- ref , err := RequiredParam [string ](request , "ref" )
372
- if err != nil {
373
- return mcp .NewToolResultError (err .Error ()), nil
374
- }
375
-
376
- // Get optional inputs parameter
377
- var inputs map [string ]interface {}
378
- if requestInputs , ok := request .GetArguments ()["inputs" ]; ok {
379
- if inputsMap , ok := requestInputs .(map [string ]interface {}); ok {
380
- inputs = inputsMap
381
- }
382
- }
383
-
384
- client , err := getClient (ctx )
385
- if err != nil {
386
- return nil , fmt .Errorf ("failed to get GitHub client: %w" , err )
387
- }
304
+ var resp * github.Response
305
+ var workflowType string
388
306
389
- event := github.CreateWorkflowDispatchEventRequest {
390
- Ref : ref ,
391
- Inputs : inputs ,
307
+ if workflowIDInt , parseErr := strconv .ParseInt (workflowID , 10 , 64 ); parseErr == nil {
308
+ resp , err = client .Actions .CreateWorkflowDispatchEventByID (ctx , owner , repo , workflowIDInt , event )
309
+ workflowType = "workflow_id"
310
+ } else {
311
+ resp , err = client .Actions .CreateWorkflowDispatchEventByFileName (ctx , owner , repo , workflowID , event )
312
+ workflowType = "workflow_file"
392
313
}
393
314
394
- resp , err := client .Actions .CreateWorkflowDispatchEventByFileName (ctx , owner , repo , workflowFile , event )
395
315
if err != nil {
396
316
return nil , fmt .Errorf ("failed to run workflow: %w" , err )
397
317
}
398
318
defer func () { _ = resp .Body .Close () }()
399
319
400
320
result := map [string ]any {
401
321
"message" : "Workflow run has been queued" ,
402
- "workflow_file" : workflowFile ,
322
+ "workflow_type" : workflowType ,
323
+ "workflow_id" : workflowID ,
403
324
"ref" : ref ,
404
325
"inputs" : inputs ,
405
326
"status" : resp .Status ,
0 commit comments