Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3e7e365

Browse files
committed
Create 'add sub-issue' tool
1 parentc2d5b43 commit3e7e365

File tree

3 files changed

+406
-0
lines changed

3 files changed

+406
-0
lines changed

‎pkg/github/issues.go

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,118 @@ func AddIssueComment(getClient GetClientFn, t translations.TranslationHelperFunc
153153
}
154154
}
155155

156+
// AddSubIssue creates a tool to add a sub-issue to a parent issue.
157+
funcAddSubIssue(getClientGetClientFn,t translations.TranslationHelperFunc) (tool mcp.Tool,handler server.ToolHandlerFunc) {
158+
returnmcp.NewTool("add_sub_issue",
159+
mcp.WithDescription(t("TOOL_ADD_SUB_ISSUE_DESCRIPTION","Add a sub-issue to a parent issue in a GitHub repository.")),
160+
mcp.WithToolAnnotation(mcp.ToolAnnotation{
161+
Title:t("TOOL_ADD_SUB_ISSUE_USER_TITLE","Add sub-issue"),
162+
ReadOnlyHint:toBoolPtr(false),
163+
}),
164+
mcp.WithString("owner",
165+
mcp.Required(),
166+
mcp.Description("Repository owner"),
167+
),
168+
mcp.WithString("repo",
169+
mcp.Required(),
170+
mcp.Description("Repository name"),
171+
),
172+
mcp.WithNumber("issue_number",
173+
mcp.Required(),
174+
mcp.Description("The number of the parent issue"),
175+
),
176+
mcp.WithNumber("sub_issue_id",
177+
mcp.Required(),
178+
mcp.Description("The ID of the sub-issue to add"),
179+
),
180+
mcp.WithBoolean("replace_parent",
181+
mcp.Description("When true, replaces the sub-issue's current parent issue"),
182+
),
183+
),
184+
func(ctx context.Context,request mcp.CallToolRequest) (*mcp.CallToolResult,error) {
185+
owner,err:=requiredParam[string](request,"owner")
186+
iferr!=nil {
187+
returnmcp.NewToolResultError(err.Error()),nil
188+
}
189+
repo,err:=requiredParam[string](request,"repo")
190+
iferr!=nil {
191+
returnmcp.NewToolResultError(err.Error()),nil
192+
}
193+
issueNumber,err:=RequiredInt(request,"issue_number")
194+
iferr!=nil {
195+
returnmcp.NewToolResultError(err.Error()),nil
196+
}
197+
subIssueID,err:=RequiredInt(request,"sub_issue_id")
198+
iferr!=nil {
199+
returnmcp.NewToolResultError(err.Error()),nil
200+
}
201+
replaceParent,err:=OptionalParam[bool](request,"replace_parent")
202+
iferr!=nil {
203+
returnmcp.NewToolResultError(err.Error()),nil
204+
}
205+
206+
client,err:=getClient(ctx)
207+
iferr!=nil {
208+
returnnil,fmt.Errorf("failed to get GitHub client: %w",err)
209+
}
210+
211+
// Create the request body
212+
requestBody:=map[string]interface{}{
213+
"sub_issue_id":subIssueID,
214+
}
215+
ifreplaceParent {
216+
requestBody["replace_parent"]=replaceParent
217+
}
218+
219+
// Since the go-github library might not have sub-issues support yet,
220+
// we'll make a direct HTTP request using the client's HTTP client
221+
reqBodyBytes,err:=json.Marshal(requestBody)
222+
iferr!=nil {
223+
returnnil,fmt.Errorf("failed to marshal request body: %w",err)
224+
}
225+
226+
url:=fmt.Sprintf("https://api.github.com/repos/%s/%s/issues/%d/sub_issues",owner,repo,issueNumber)
227+
req,err:=http.NewRequestWithContext(ctx,"POST",url,strings.NewReader(string(reqBodyBytes)))
228+
iferr!=nil {
229+
returnnil,fmt.Errorf("failed to create request: %w",err)
230+
}
231+
232+
req.Header.Set("Accept","application/vnd.github+json")
233+
req.Header.Set("Content-Type","application/json")
234+
req.Header.Set("X-GitHub-Api-Version","2022-11-28")
235+
236+
// Use the same authentication as the GitHub client
237+
httpClient:=client.Client()
238+
resp,err:=httpClient.Do(req)
239+
iferr!=nil {
240+
returnnil,fmt.Errorf("failed to add sub-issue: %w",err)
241+
}
242+
deferfunc() {_=resp.Body.Close() }()
243+
244+
body,err:=io.ReadAll(resp.Body)
245+
iferr!=nil {
246+
returnnil,fmt.Errorf("failed to read response body: %w",err)
247+
}
248+
249+
ifresp.StatusCode!=http.StatusCreated {
250+
returnmcp.NewToolResultError(fmt.Sprintf("failed to add sub-issue: %s",string(body))),nil
251+
}
252+
253+
// Parse and re-marshal to ensure consistent formatting
254+
varresultinterface{}
255+
iferr:=json.Unmarshal(body,&result);err!=nil {
256+
returnnil,fmt.Errorf("failed to unmarshal response: %w",err)
257+
}
258+
259+
r,err:=json.Marshal(result)
260+
iferr!=nil {
261+
returnnil,fmt.Errorf("failed to marshal response: %w",err)
262+
}
263+
264+
returnmcp.NewToolResultText(string(r)),nil
265+
}
266+
}
267+
156268
// SearchIssues creates a tool to search for issues and pull requests.
157269
funcSearchIssues(getClientGetClientFn,t translations.TranslationHelperFunc) (tool mcp.Tool,handler server.ToolHandlerFunc) {
158270
returnmcp.NewTool("search_issues",

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp