Skip to content

Commit 6793b9d

Browse files
JoannaaKLCopilot
andauthored
Add tools to add, update and delete project items (#1152)
* Add add_project_item tool * Add tools to update and delete project items * Update pkg/github/projects.go Co-authored-by: Copilot <[email protected]> * Update pkg/github/projects.go Co-authored-by: Copilot <[email protected]> * Add tests * Lint the code * Fix req params --------- Co-authored-by: Copilot <[email protected]>
1 parent 0885601 commit 6793b9d

File tree

10 files changed

+1077
-9
lines changed

10 files changed

+1077
-9
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,19 @@ The following sets of tools are available (all are on by default):
658658

659659
<summary>Projects</summary>
660660

661+
- **add_project_item** - Add project item
662+
- `item_id`: The numeric ID of the issue or pull request to add to the project. (number, required)
663+
- `item_type`: The item's type, either issue or pull_request. (string, required)
664+
- `owner`: If owner_type == user it is the handle for the GitHub user account. If owner_type == org it is the name of the organization. The name is not case sensitive. (string, required)
665+
- `owner_type`: Owner type (string, required)
666+
- `project_number`: The project's number. (number, required)
667+
668+
- **delete_project_item** - Delete project item
669+
- `item_id`: The internal project item ID to delete from the project (not the issue or pull request ID). (number, required)
670+
- `owner`: If owner_type == user it is the handle for the GitHub user account. If owner_type == org it is the name of the organization. The name is not case sensitive. (string, required)
671+
- `owner_type`: Owner type (string, required)
672+
- `project_number`: The project's number. (number, required)
673+
661674
- **get_project** - Get project
662675
- `owner`: If owner_type == user it is the handle for the GitHub user account. If owner_type == org it is the name of the organization. The name is not case sensitive. (string, required)
663676
- `owner_type`: Owner type (string, required)
@@ -694,6 +707,13 @@ The following sets of tools are available (all are on by default):
694707
- `per_page`: Number of results per page (max 100, default: 30) (number, optional)
695708
- `query`: Filter projects by a search query (matches title and description) (string, optional)
696709

710+
- **update_project_item** - Update project item
711+
- `fields`: A list of field updates to apply. (array, required)
712+
- `item_id`: The numeric ID of the project item to update (not the issue or pull request ID). (number, required)
713+
- `owner`: If owner_type == user it is the handle for the GitHub user account. If owner_type == org it is the name of the organization. The name is not case sensitive. (string, required)
714+
- `owner_type`: Owner type (string, required)
715+
- `project_number`: The project's number. (number, required)
716+
697717
</details>
698718

699719
<details>

internal/ghmcp/server.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ func NewMCPServer(cfg MCPServerConfig) (*server.MCPServer, error) {
118118

119119
// Generate instructions based on enabled toolsets
120120
instructions := github.GenerateInstructions(enabledToolsets)
121-
122-
ghServer := github.NewServer(cfg.Version,
121+
122+
ghServer := github.NewServer(cfg.Version,
123123
server.WithInstructions(instructions),
124124
server.WithHooks(hooks),
125125
)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"annotations": {
3+
"title": "Add project item",
4+
"readOnlyHint": false
5+
},
6+
"description": "Add a specific Project item for a user or org",
7+
"inputSchema": {
8+
"properties": {
9+
"item_id": {
10+
"description": "The numeric ID of the issue or pull request to add to the project.",
11+
"type": "number"
12+
},
13+
"item_type": {
14+
"description": "The item's type, either issue or pull_request.",
15+
"enum": [
16+
"issue",
17+
"pull_request"
18+
],
19+
"type": "string"
20+
},
21+
"owner": {
22+
"description": "If owner_type == user it is the handle for the GitHub user account. If owner_type == org it is the name of the organization. The name is not case sensitive.",
23+
"type": "string"
24+
},
25+
"owner_type": {
26+
"description": "Owner type",
27+
"enum": [
28+
"user",
29+
"org"
30+
],
31+
"type": "string"
32+
},
33+
"project_number": {
34+
"description": "The project's number.",
35+
"type": "number"
36+
}
37+
},
38+
"required": [
39+
"owner_type",
40+
"owner",
41+
"project_number",
42+
"item_type",
43+
"item_id"
44+
],
45+
"type": "object"
46+
},
47+
"name": "add_project_item"
48+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"annotations": {
3+
"title": "Delete project item",
4+
"readOnlyHint": false
5+
},
6+
"description": "Delete a specific Project item for a user or org",
7+
"inputSchema": {
8+
"properties": {
9+
"item_id": {
10+
"description": "The internal project item ID to delete from the project (not the issue or pull request ID).",
11+
"type": "number"
12+
},
13+
"owner": {
14+
"description": "If owner_type == user it is the handle for the GitHub user account. If owner_type == org it is the name of the organization. The name is not case sensitive.",
15+
"type": "string"
16+
},
17+
"owner_type": {
18+
"description": "Owner type",
19+
"enum": [
20+
"user",
21+
"org"
22+
],
23+
"type": "string"
24+
},
25+
"project_number": {
26+
"description": "The project's number.",
27+
"type": "number"
28+
}
29+
},
30+
"required": [
31+
"owner_type",
32+
"owner",
33+
"project_number",
34+
"item_id"
35+
],
36+
"type": "object"
37+
},
38+
"name": "delete_project_item"
39+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"annotations": {
3+
"title": "Update project item",
4+
"readOnlyHint": false
5+
},
6+
"description": "Update a specific Project item for a user or org",
7+
"inputSchema": {
8+
"properties": {
9+
"fields": {
10+
"description": "A list of field updates to apply.",
11+
"type": "array"
12+
},
13+
"item_id": {
14+
"description": "The numeric ID of the project item to update (not the issue or pull request ID).",
15+
"type": "number"
16+
},
17+
"owner": {
18+
"description": "If owner_type == user it is the handle for the GitHub user account. If owner_type == org it is the name of the organization. The name is not case sensitive.",
19+
"type": "string"
20+
},
21+
"owner_type": {
22+
"description": "Owner type",
23+
"enum": [
24+
"user",
25+
"org"
26+
],
27+
"type": "string"
28+
},
29+
"project_number": {
30+
"description": "The project's number.",
31+
"type": "number"
32+
}
33+
},
34+
"required": [
35+
"owner_type",
36+
"owner",
37+
"project_number",
38+
"item_id",
39+
"fields"
40+
],
41+
"type": "object"
42+
},
43+
"name": "update_project_item"
44+
}

pkg/github/instructions.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,21 @@ func GenerateInstructions(enabledToolsets []string) string {
1212
if os.Getenv("DISABLE_INSTRUCTIONS") == "true" {
1313
return "" // Baseline mode
1414
}
15-
15+
1616
var instructions []string
17-
17+
1818
// Core instruction - always included if context toolset enabled
1919
if slices.Contains(enabledToolsets, "context") {
2020
instructions = append(instructions, "Always call 'get_me' first to understand current user permissions and context.")
2121
}
22-
22+
2323
// Individual toolset instructions
2424
for _, toolset := range enabledToolsets {
2525
if inst := getToolsetInstructions(toolset); inst != "" {
2626
instructions = append(instructions, inst)
2727
}
2828
}
29-
29+
3030
// Base instruction with context management
3131
baseInstruction := `The GitHub MCP Server provides tools to interact with GitHub platform.
3232
@@ -40,7 +40,7 @@ Context management:
4040

4141
allInstructions := []string{baseInstruction}
4242
allInstructions = append(allInstructions, instructions...)
43-
43+
4444
return strings.Join(allInstructions, " ")
4545
}
4646

@@ -57,4 +57,3 @@ func getToolsetInstructions(toolset string) string {
5757
return ""
5858
}
5959
}
60-

pkg/github/instructions_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,4 +163,4 @@ func TestGetToolsetInstructions(t *testing.T) {
163163
}
164164
})
165165
}
166-
}
166+
}

0 commit comments

Comments
 (0)