@@ -404,7 +404,7 @@ func ListBranches(t translations.TranslationHelperFunc) inventory.ServerTool {
404404
405405// CreateOrUpdateFile creates a tool to create or update a file in a GitHub repository.
406406func CreateOrUpdateFile (t translations.TranslationHelperFunc ) inventory.ServerTool {
407- return NewTool (
407+ tool := NewTool (
408408 ToolsetMetadataRepos ,
409409 mcp.Tool {
410410 Name : "create_or_update_file" ,
@@ -469,6 +469,10 @@ SHA MUST be provided for existing file updates.
469469 if err != nil {
470470 return utils .NewToolResultError (err .Error ()), nil , nil
471471 }
472+ path , err = validateRelativePath (path )
473+ if err != nil {
474+ return utils .NewToolResultError (fmt .Sprintf ("invalid path: %s" , err )), nil , nil
475+ }
472476 content , err := RequiredParam [string ](args , "content" )
473477 if err != nil {
474478 return utils .NewToolResultError (err .Error ()), nil , nil
@@ -507,8 +511,6 @@ SHA MUST be provided for existing file updates.
507511 return nil , nil , fmt .Errorf ("failed to get GitHub client: %w" , err )
508512 }
509513
510- path = strings .TrimPrefix (path , "/" )
511-
512514 // SHA validation using Contents API to fetch current file metadata (blob SHA)
513515 getOpts := & github.RepositoryContentGetOptions {Ref : branch }
514516
@@ -596,6 +598,8 @@ SHA MUST be provided for existing file updates.
596598 return MarshalledTextResult (minimalResponse ), nil , nil
597599 },
598600 )
601+ tool .ScopeResolver = workflowScopeForPath
602+ return tool
599603}
600604
601605// CreateRepository creates a tool to create a new GitHub repository.
@@ -1244,7 +1248,7 @@ func ForkRepository(t translations.TranslationHelperFunc) inventory.ServerTool {
12441248// The approach implemented here gets automatic commit signing when used with either the github-actions user or as an app,
12451249// both of which suit an LLM well.
12461250func DeleteFile (t translations.TranslationHelperFunc ) inventory.ServerTool {
1247- return NewTool (
1251+ tool := NewTool (
12481252 ToolsetMetadataRepos ,
12491253 mcp.Tool {
12501254 Name : "delete_file" ,
@@ -1295,6 +1299,10 @@ func DeleteFile(t translations.TranslationHelperFunc) inventory.ServerTool {
12951299 if err != nil {
12961300 return utils .NewToolResultError (err .Error ()), nil , nil
12971301 }
1302+ path , err = validateRelativePath (path )
1303+ if err != nil {
1304+ return utils .NewToolResultError (fmt .Sprintf ("invalid path: %s" , err )), nil , nil
1305+ }
12981306 message , err := RequiredParam [string ](args , "message" )
12991307 if err != nil {
13001308 return utils .NewToolResultError (err .Error ()), nil , nil
@@ -1425,6 +1433,8 @@ func DeleteFile(t translations.TranslationHelperFunc) inventory.ServerTool {
14251433 return utils .NewToolResultText (string (r )), nil , nil
14261434 },
14271435 )
1436+ tool .ScopeResolver = workflowScopeForPath
1437+ return tool
14281438}
14291439
14301440// CreateBranch creates a tool to create a new branch.
@@ -1542,7 +1552,7 @@ func CreateBranch(t translations.TranslationHelperFunc) inventory.ServerTool {
15421552
15431553// PushFiles creates a tool to push multiple files in a single commit to a GitHub repository.
15441554func PushFiles (t translations.TranslationHelperFunc ) inventory.ServerTool {
1545- return NewTool (
1555+ tool := NewTool (
15461556 ToolsetMetadataRepos ,
15471557 mcp.Tool {
15481558 Name : "push_files" ,
@@ -1618,6 +1628,35 @@ func PushFiles(t translations.TranslationHelperFunc) inventory.ServerTool {
16181628 return utils .NewToolResultError ("files parameter must be an array of objects with path and content" ), nil , nil
16191629 }
16201630
1631+ entries := make ([]* github.TreeEntry , 0 , len (filesObj ))
1632+ for _ , file := range filesObj {
1633+ fileMap , ok := file .(map [string ]any )
1634+ if ! ok {
1635+ return utils .NewToolResultError ("each file must be an object with path and content" ), nil , nil
1636+ }
1637+
1638+ filePath , ok := fileMap ["path" ].(string )
1639+ if ! ok || filePath == "" {
1640+ return utils .NewToolResultError ("each file must have a path" ), nil , nil
1641+ }
1642+ filePath , err = validateRelativePath (filePath )
1643+ if err != nil {
1644+ return utils .NewToolResultError (fmt .Sprintf ("invalid file path: %s" , err )), nil , nil
1645+ }
1646+
1647+ content , ok := fileMap ["content" ].(string )
1648+ if ! ok {
1649+ return utils .NewToolResultError ("each file must have content" ), nil , nil
1650+ }
1651+
1652+ entries = append (entries , & github.TreeEntry {
1653+ Path : github .Ptr (filePath ),
1654+ Mode : github .Ptr ("100644" ),
1655+ Type : github .Ptr ("blob" ),
1656+ Content : github .Ptr (content ),
1657+ })
1658+ }
1659+
16211660 client , err := deps .GetClient (ctx )
16221661 if err != nil {
16231662 return nil , nil , fmt .Errorf ("failed to get GitHub client: %w" , err )
@@ -1691,34 +1730,6 @@ func PushFiles(t translations.TranslationHelperFunc) inventory.ServerTool {
16911730 baseCommit = base
16921731 }
16931732
1694- // Create tree entries for all files (or remaining files if empty repo)
1695- var entries []* github.TreeEntry
1696-
1697- for _ , file := range filesObj {
1698- fileMap , ok := file .(map [string ]any )
1699- if ! ok {
1700- return utils .NewToolResultError ("each file must be an object with path and content" ), nil , nil
1701- }
1702-
1703- path , ok := fileMap ["path" ].(string )
1704- if ! ok || path == "" {
1705- return utils .NewToolResultError ("each file must have a path" ), nil , nil
1706- }
1707-
1708- content , ok := fileMap ["content" ].(string )
1709- if ! ok {
1710- return utils .NewToolResultError ("each file must have content" ), nil , nil
1711- }
1712-
1713- // Create a tree entry for the file
1714- entries = append (entries , & github.TreeEntry {
1715- Path : github .Ptr (path ),
1716- Mode : github .Ptr ("100644" ), // Regular file mode
1717- Type : github .Ptr ("blob" ),
1718- Content : github .Ptr (content ),
1719- })
1720- }
1721-
17221733 // Create a new tree with the file entries (baseCommit is now guaranteed to exist)
17231734 newTree , resp , err := client .Git .CreateTree (ctx , owner , repo , * baseCommit .Tree .SHA , entries )
17241735 if err != nil {
@@ -1773,6 +1784,8 @@ func PushFiles(t translations.TranslationHelperFunc) inventory.ServerTool {
17731784 return utils .NewToolResultText (string (r )), nil , nil
17741785 },
17751786 )
1787+ tool .ScopeResolver = workflowScopeForFiles
1788+ return tool
17761789}
17771790
17781791// ListTags creates a tool to list tags in a GitHub repository.
0 commit comments